UEsDBAoAAAAAAAAAIQAmbx6fMgAAADIAAAAUAAAATUVUQS1JTkYvTUFOSUZFU1QuTUZNYW5pZmVzdC1WZXJzaW9uOiAxLjAKQ3JlYXRlZC1CeTogMS42LjAgKHByb3RvYykKClBLAwQKAAAAAAAAACEAPLg444pZAACKWQAAGgAAAGFueV90ZXN0L0FueVRlc3RQcm90by5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL2FueV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBhbnlfdGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBBbnlUZXN0UHJvdG8gewogIHByaXZhdGUgQW55VGVzdFByb3RvKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RBbnlPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6YW55X3Rlc3QuVGVzdEFueSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIGdldFZhbHVlT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGFueV90ZXN0LlRlc3RBbnl9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0QW55IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmFueV90ZXN0LlRlc3RBbnkpCiAgICAgIFRlc3RBbnlPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RBbnkubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEFueShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RBbnkoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEFueSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGFueV90ZXN0LkFueVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfYW55X3Rlc3RfVGVzdEFueV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGFueV90ZXN0LkFueVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfYW55X3Rlc3RfVGVzdEFueV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55LmNsYXNzLCBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWVfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldFZhbHVlKCkgewogICAgICByZXR1cm4gdmFsdWVfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHZhbHVlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIGdldFZhbHVlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gdmFsdWVfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHZhbHVlXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0VmFsdWUoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRWYWx1ZSgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgb3RoZXIgPSAoYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkpIG9iajsKCiAgICAgIGlmIChoYXNWYWx1ZSgpICE9IG90aGVyLmhhc1ZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICBpZiAoIWdldFZhbHVlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRWYWx1ZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGFueV90ZXN0LlRlc3RBbnl9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czphbnlfdGVzdC5UZXN0QW55KQogICAgICAgIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGFueV90ZXN0LkFueVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfYW55X3Rlc3RfVGVzdEFueV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2FueV90ZXN0X1Rlc3RBbnlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkuY2xhc3MsIGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0VmFsdWVGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHZhbHVlXyA9IG51bGw7CiAgICAgICAgaWYgKHZhbHVlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgdmFsdWVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICB2YWx1ZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGFueV90ZXN0LkFueVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfYW55X3Rlc3RfVGVzdEFueV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgYnVpbGQoKSB7CiAgICAgICAgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgcmVzdWx0ID0gbmV3IGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55KHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGFueV90ZXN0LkFueVRlc3RQcm90by5UZXN0QW55IHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnZhbHVlXyA9IHZhbHVlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gdmFsdWVfCiAgICAgICAgICAgICAgOiB2YWx1ZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICBtZXJnZVZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRWYWx1ZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gdmFsdWVCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRWYWx1ZSgpIHsKICAgICAgICBpZiAodmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gdmFsdWVfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHZhbHVlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHZhbHVlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB2YWx1ZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdmFsdWVCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VmFsdWUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmICh2YWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHZhbHVlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB2YWx1ZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIHZhbHVlXyAhPSBudWxsICYmCiAgICAgICAgICAgIHZhbHVlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRWYWx1ZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFsdWVfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHZhbHVlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKHZhbHVlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB2YWx1ZV8gPSBudWxsOwogICAgICAgIGlmICh2YWx1ZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHZhbHVlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgdmFsdWVCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgZ2V0VmFsdWVCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0VmFsdWVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0VmFsdWVPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHZhbHVlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHZhbHVlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdmFsdWVfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpIDogdmFsdWVfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRWYWx1ZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAodmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICB2YWx1ZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0VmFsdWUoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHZhbHVlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmFueV90ZXN0LlRlc3RBbnkpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmFueV90ZXN0LlRlc3RBbnkpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYW55X3Rlc3QuQW55VGVzdFByb3RvLlRlc3RBbnkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QW55PgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RBbnk+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0QW55IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFueT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QW55PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBhbnlfdGVzdC5BbnlUZXN0UHJvdG8uVGVzdEFueSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19hbnlfdGVzdF9UZXN0QW55X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2FueV90ZXN0X1Rlc3RBbnlfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcblwiY29tL2dvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5wcm90b1wwMjJcMDEwYW4iICsKICAgICAgInlfdGVzdFwwMzJcMDMxZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90b1wiLlxuXDAwN1RlcyIgKwogICAgICAidEFueVwwMjIjXG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAxKFwwMTMyXDAyNC5nb29nbGUucHJvdG9idWYuQW4iICsKICAgICAgInlCXDAzMFxuXDAxMGFueV90ZXN0QlwwMTRBbnlUZXN0UHJvdG9iXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlQcm90by5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfYW55X3Rlc3RfVGVzdEFueV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19hbnlfdGVzdF9UZXN0QW55X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2FueV90ZXN0X1Rlc3RBbnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgfSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueVByb3RvLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAAiV2lSybwUAsm8FAC8AAABjb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9maWVsZF9wcmVzZW5jZV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmOwoKcHVibGljIGZpbmFsIGNsYXNzIEZpZWxkUHJlc2VuY2VUZXN0UHJvdG8gewogIHByaXZhdGUgRmllbGRQcmVzZW5jZVRlc3RQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQcm90bzJNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQcm90bzJNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9pbnQzMiA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZJbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9pbnQzMiA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPbmVvZkludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICovCiAgICBpbnQgZ2V0T25lb2ZVaW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T25lb2ZTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T25lb2ZTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb25lb2ZfbmVzdGVkX2VudW0gPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mTmVzdGVkRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRFbnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9uZW9mX25lc3RlZF9lbnVtID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvbmVvZk5lc3RlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRPbmVvZk5lc3RlZEVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvbmVvZl9uZXN0ZWRfZW51bSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTmVzdGVkRW51bS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9uZW9mTmVzdGVkRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9uZW9mX3Byb3RvMl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlByb3RvMk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mUHJvdG8yTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9uZW9mX3Byb3RvMl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZQcm90bzJNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRPbmVvZlByb3RvMk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvbmVvZl9wcm90bzJfbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0T25lb2ZQcm90bzJNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFJlcGVhdGVkQnl0ZXNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gCiAgICAgICAgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFBhY2tlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UGFja2VkTmVzdGVkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcGFja2VkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KTsKCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9uZW9mRmllbGRDYXNlIGdldE9uZW9mRmllbGRDYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEFsbFR5cGVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzKQogICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoKSB7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHBhY2tlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIGZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIE5lc3RlZEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMiksCiAgICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9WQUxVRSA9IDI7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBWjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgTmVzdGVkRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgaW50IGdldFZhbHVlKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICh2YWx1ZV8gIT0gMCkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKHZhbHVlXyAhPSAwKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChnZXRWYWx1ZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFZhbHVlKCk7CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuZ2V0VmFsdWUoKSAhPSAwKSB7CiAgICAgICAgICAgIHNldFZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIHZhbHVlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKGludCB2YWx1ZSkgewoKICAgICAgICAgIHZhbHVlXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJWYWx1ZSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpmaWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRNZXNzYWdlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgcHVibGljIGVudW0gT25lb2ZGaWVsZENhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgT05FT0ZfSU5UMzIoMTEpLAogICAgICBPTkVPRl9VSU5UMzIoMTIpLAogICAgICBPTkVPRl9TVFJJTkcoMTMpLAogICAgICBPTkVPRl9CWVRFUygxNCksCiAgICAgIE9ORU9GX05FU1RFRF9FTlVNKDE1KSwKICAgICAgT05FT0ZfTkVTVEVEX01FU1NBR0UoMTYpLAogICAgICBPTkVPRl9QUk9UTzJfTUVTU0FHRSgxNyksCiAgICAgIE9ORU9GRklFTERfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgT25lb2ZGaWVsZENhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDExOiByZXR1cm4gT05FT0ZfSU5UMzI7CiAgICAgICAgICBjYXNlIDEyOiByZXR1cm4gT05FT0ZfVUlOVDMyOwogICAgICAgICAgY2FzZSAxMzogcmV0dXJuIE9ORU9GX1NUUklORzsKICAgICAgICAgIGNhc2UgMTQ6IHJldHVybiBPTkVPRl9CWVRFUzsKICAgICAgICAgIGNhc2UgMTU6IHJldHVybiBPTkVPRl9ORVNURURfRU5VTTsKICAgICAgICAgIGNhc2UgMTY6IHJldHVybiBPTkVPRl9ORVNURURfTUVTU0FHRTsKICAgICAgICAgIGNhc2UgMTc6IHJldHVybiBPTkVPRl9QUk9UTzJfTUVTU0FHRTsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIE9ORU9GRklFTERfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICByZXR1cm4gT25lb2ZGaWVsZENhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHM7CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQnl0ZXNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGludCBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1BST1RPMl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQcm90bzJNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxQcm90bzJNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUHJvdG8yTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQcm90bzJNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFByb3RvMk1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgb25lb2ZfaW50MzIgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZkludDMyKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9pbnQzMiA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZJbnQzMigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX1VJTlQzMl9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mU3RyaW5nKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDEzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEzKSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9CWVRFU19GSUVMRF9OVU1CRVIgPSAxNDsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZkJ5dGVzKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCkgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvbmVvZl9uZXN0ZWRfZW51bSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRFbnVtKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvbmVvZl9uZXN0ZWRfZW51bSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb25lb2ZOZXN0ZWRFbnVtLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldE9uZW9mTmVzdGVkRW51bVZhbHVlKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE1KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9uZW9mX25lc3RlZF9lbnVtID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRFbnVtLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9uZW9mTmVzdGVkRW51bSgpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKAogICAgICAgICAgICAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9POwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE2OwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTmVzdGVkTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpIHsKICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgewogICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9QUk9UTzJfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxNzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvbmVvZl9wcm90bzJfbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZQcm90bzJNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZQcm90bzJNZXNzYWdlKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9uZW9mX3Byb3RvMl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZQcm90bzJNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0T25lb2ZQcm90bzJNZXNzYWdlKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvbmVvZl9wcm90bzJfbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldE9uZW9mUHJvdG8yTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSID0gMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfRklFTERfTlVNQkVSID0gMjI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9CWVRFU19GSUVMRF9OVU1CRVIgPSAyMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLlByb3RvYnVmTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHJlcGVhdGVkQnl0ZXNfID0KICAgICAgICBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAyNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9QUk9UTzJfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZE5lc3RlZEVudW1fOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gcGFja2VkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRQYWNrZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocGFja2VkTmVzdGVkRW51bV8sIHBhY2tlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcGFja2VkX25lc3RlZF9lbnVtID0gMjcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UGFja2VkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHBhY2tlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoaGFzT3B0aW9uYWxQcm90bzJNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGhhc09uZW9mUHJvdG8yTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPbmVvZlByb3RvMk1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlQ291bnQoKTsgaSsrKSB7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmIChvcHRpb25hbEludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ18pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMywgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDQsIG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNSwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDExLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMikgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigKICAgICAgICAgICAgMTIsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEzKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMywgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygKICAgICAgICAgICAgMTQsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE1KSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxNSwgKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxNiwgKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE3LCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMTcwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcocmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjIsIHJlcGVhdGVkU3RyaW5nXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygyMywgcmVwZWF0ZWRCeXRlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygxOTQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyNSwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjYsIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkTmVzdGVkRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjE4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhwYWNrZWROZXN0ZWRFbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAob3B0aW9uYWxJbnQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ18pKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyLCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgzLCBvcHRpb25hbEJ5dGVzXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkRW51bV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTy5nZXROdW1iZXIoKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSg0LCBvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMTEsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMTIsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMywgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKAogICAgICAgICAgICAgIDE0LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxNSwgKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNywgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemVOb1RhZyhyZXBlYXRlZEJ5dGVzXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cmVwZWF0ZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNSwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNiwgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHBhY2tlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWROZXN0ZWRFbnVtTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cGFja2VkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMpIG9iajsKCiAgICAgIGlmIChnZXRPcHRpb25hbEludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbEJ5dGVzKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSBvdGhlci5vcHRpb25hbE5lc3RlZEVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbExhenlNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbExhenlNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEJ5dGVzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkTmVzdGVkRW51bV8uZXF1YWxzKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5wYWNrZWROZXN0ZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPbmVvZkZpZWxkQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgMTE6CiAgICAgICAgICBpZiAoZ2V0T25lb2ZJbnQzMigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T25lb2ZJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgaWYgKGdldE9uZW9mVWludDMyKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPbmVvZlVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDEzOgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZlN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNDoKICAgICAgICAgIGlmICghZ2V0T25lb2ZCeXRlcygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZkJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgaWYgKGdldE9uZW9mTmVzdGVkRW51bVZhbHVlKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPbmVvZk5lc3RlZEVudW1WYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgaWYgKCFnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE3OgogICAgICAgICAgaWYgKCFnZXRPbmVvZlByb3RvMk1lc3NhZ2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZQcm90bzJNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfUFJPVE8yX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkTmVzdGVkRW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfUFJPVE8yX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHBhY2tlZE5lc3RlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgc3dpdGNoIChvbmVvZkZpZWxkQ2FzZV8pIHsKICAgICAgICBjYXNlIDExOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZJbnQzMigpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZlVpbnQzMigpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZlN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZOZXN0ZWRFbnVtVmFsdWUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX1BST1RPMl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mUHJvdG8yTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBpZiAob25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIHBhY2tlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkRW51bV8gPSByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRQcm90bzJNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkTmVzdGVkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucGFja2VkTmVzdGVkRW51bV8gPSBwYWNrZWROZXN0ZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzJfID0gb3B0aW9uYWxJbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdfID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQnl0ZXNfID0gb3B0aW9uYWxCeXRlc187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRFbnVtXyA9IG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICAgICAgfQogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPSBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbFByb3RvMk1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTGF6eU1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDMyXyA9IHJlcGVhdGVkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZ18gPSByZXBlYXRlZFN0cmluZ187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCeXRlc18gPSByZXBlYXRlZEJ5dGVzXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkQ2FzZV8gPSBvbmVvZkZpZWxkQ2FzZV87CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gdGhpcy5vbmVvZkZpZWxkXzsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2ICYmCiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcgJiYKICAgICAgICAgICAgb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpICE9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSkgewogICAgICAgICAgc2V0T3B0aW9uYWxCeXRlcyhvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIub3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZShvdGhlci5nZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbFByb3RvMk1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsTGF6eU1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5yZXBlYXRlZEludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZ18gPSBvdGhlci5yZXBlYXRlZFN0cmluZ187CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IG90aGVyLnJlcGVhdGVkQnl0ZXNfOwogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkQWxsKG90aGVyLnJlcGVhdGVkQnl0ZXNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRQcm90bzJNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRQcm90bzJNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkUHJvdG8yTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWROZXN0ZWRFbnVtXyA9IG90aGVyLnBhY2tlZE5lc3RlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZE5lc3RlZEVudW1fLmFkZEFsbChvdGhlci5wYWNrZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIE9ORU9GX0lOVDMyOiB7CiAgICAgICAgICAgIHNldE9uZW9mSW50MzIob3RoZXIuZ2V0T25lb2ZJbnQzMigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX1VJTlQzMjogewogICAgICAgICAgICBzZXRPbmVvZlVpbnQzMihvdGhlci5nZXRPbmVvZlVpbnQzMigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX1NUUklORzogewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMzsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBvdGhlci5vbmVvZkZpZWxkXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9CWVRFUzogewogICAgICAgICAgICBzZXRPbmVvZkJ5dGVzKG90aGVyLmdldE9uZW9mQnl0ZXMoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9ORVNURURfRU5VTTogewogICAgICAgICAgICBzZXRPbmVvZk5lc3RlZEVudW1WYWx1ZShvdGhlci5nZXRPbmVvZk5lc3RlZEVudW1WYWx1ZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX05FU1RFRF9NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlT25lb2ZOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9uZW9mTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX1BST1RPMl9NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlT25lb2ZQcm90bzJNZXNzYWdlKG90aGVyLmdldE9uZW9mUHJvdG8yTWVzc2FnZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GRklFTERfTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmIChoYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSkgewogICAgICAgICAgaWYgKCFnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaGFzT25lb2ZQcm90bzJNZXNzYWdlKCkpIHsKICAgICAgICAgIGlmICghZ2V0T25lb2ZQcm90bzJNZXNzYWdlKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VDb3VudCgpOyBpKyspIHsKICAgICAgICAgIGlmICghZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlKGkpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDg4OiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODgKICAgICAgICAgICAgICBjYXNlIDk2OiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDEyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2CiAgICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTM7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMDogewogICAgICAgICAgICAgICAgaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE1OwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSByYXdWYWx1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjAKICAgICAgICAgICAgICBjYXNlIDEzMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE2OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMAogICAgICAgICAgICAgIGNhc2UgMTM4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPbmVvZlByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM4CiAgICAgICAgICAgICAgY2FzZSAxNjg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3MAogICAgICAgICAgICAgIGNhc2UgMTc4OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3OAogICAgICAgICAgICAgIGNhc2UgMTg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4NgogICAgICAgICAgICAgIGNhc2UgMTkyOiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTIKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5NAogICAgICAgICAgICAgIGNhc2UgMjAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDIKICAgICAgICAgICAgICBjYXNlIDIxMDogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTAKICAgICAgICAgICAgICBjYXNlIDIxNjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWROZXN0ZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTYKICAgICAgICAgICAgICBjYXNlIDIxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcGFja2VkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZygpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsQnl0ZXMoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRPcHRpb25hbE5lc3RlZEVudW0oKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIob3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZEVudW0oY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBvcHRpb25hbFByb3RvMk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUHJvdG8yTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUHJvdG8yTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFByb3RvMk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHJvdG8yTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbFByb3RvMk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxQcm90bzJNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFByb3RvMk1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5TWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTGF6eU1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTGF6eU1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgb25lb2ZfaW50MzIgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZkludDMyKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9uZW9mX2ludDMyID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRPbmVvZkludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgb25lb2ZfaW50MzIgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb25lb2ZJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9uZW9mX2ludDMyID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mSW50MzIoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTIpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMjsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mVWludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTIpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEzKSB7CiAgICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMzsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mU3RyaW5nKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMzsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZkJ5dGVzKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb25lb2ZCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNDsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvbmVvZl9uZXN0ZWRfZW51bSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZEVudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZEVudW0oKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxNTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb25lb2ZfbmVzdGVkX2VudW0gPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb25lb2ZOZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9uZW9mTmVzdGVkRW51bVZhbHVlKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIHJldHVybiAoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykuaW50VmFsdWUoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9uZW9mX25lc3RlZF9lbnVtID0gMTU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb25lb2ZOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTU7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb25lb2ZfbmVzdGVkX2VudW0gPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRPbmVvZk5lc3RlZEVudW0oKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIoCiAgICAgICAgICAgICAgKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXyk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb25lb2ZfbmVzdGVkX2VudW0gPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb25lb2ZOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRFbnVtKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTU7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb25lb2ZfbmVzdGVkX2VudW0gPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZOZXN0ZWRFbnVtKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxNjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTmVzdGVkTWVzc2FnZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgewogICAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE2OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9uZW9mTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNiAmJgogICAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpIHsKICAgICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgJiYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKG9uZW9mRmllbGRDYXNlXyA9PSAxNikpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9uZW9mX3Byb3RvMl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mUHJvdG8yTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mUHJvdG8yTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE3OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9uZW9mX3Byb3RvMl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlByb3RvMk1lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRPbmVvZlByb3RvMk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9uZW9mUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCkgb25lb2ZGaWVsZF87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpIHsKICAgICAgICAgICAgcmV0dXJuIG9uZW9mUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb25lb2ZfcHJvdG8yX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlByb3RvMk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvbmVvZl9wcm90bzJfbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE3OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9uZW9mX3Byb3RvMl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPbmVvZlByb3RvMk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNyAmJgogICAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpIHsKICAgICAgICAgICAgb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvbmVvZl9wcm90bzJfbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZQcm90bzJNZXNzYWdlKCkgewogICAgICAgIGlmIChvbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZQcm90bzJNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb25lb2ZfcHJvdG8yX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBnZXRPbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRPbmVvZlByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb25lb2ZfcHJvdG8yX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPbmVvZlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpICYmIChvbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgICAgcmV0dXJuIG9uZW9mUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb25lb2ZfcHJvdG8yX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE3OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBvbmVvZlByb3RvMk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDMyKCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmcoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQnl0ZXNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJ5dGVzKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQnl0ZXNfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCeXRlcyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQnl0ZXMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEJ5dGVzKCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPihyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkUHJvdG8yTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+KHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRQcm90bzJNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFByb3RvMk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJvdG8yTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRQcm90bzJNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJvdG8yTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkUHJvdG8yTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkUHJvdG8yTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGFkZFJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGFkZFJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZE5lc3RlZEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHBhY2tlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRQYWNrZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KHBhY2tlZE5lc3RlZEVudW1fLCBwYWNrZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcGFja2VkX25lc3RlZF9lbnVtID0gMjcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRQYWNrZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcGFja2VkX25lc3RlZF9lbnVtID0gMjcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWROZXN0ZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcGFja2VkX25lc3RlZF9lbnVtID0gMjcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkTmVzdGVkRW51bShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkTmVzdGVkRW51bSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZE5lc3RlZEVudW0oKSB7CiAgICAgICAgcGFja2VkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBwYWNrZWRfbmVzdGVkX2VudW0gPSAyNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBwYWNrZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRQYWNrZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChwYWNrZWROZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHBhY2tlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHBhY2tlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVBhY2tlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcGFja2VkX25lc3RlZF9lbnVtID0gMjcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHBhY2tlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWROZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUGFja2VkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHBhY2tlZF9uZXN0ZWRfZW51bSA9IDI3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHBhY2tlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RBbGxUeXBlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RBbGxUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0T3B0aW9uYWxGaWVsZHNPbmx5T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdE9wdGlvbmFsRmllbGRzT25seSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdGlvbmFsQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRPcHRpb25hbE5lc3RlZEVudW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFByb3RvMk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFByb3RvMk1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5TWVzc2FnZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE9wdGlvbmFsRmllbGRzT25seSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpmaWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RPcHRpb25hbEZpZWxkc09ubHkpCiAgICAgIFRlc3RPcHRpb25hbEZpZWxkc09ubHlPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RPcHRpb25hbEZpZWxkc09ubHkubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE9wdGlvbmFsRmllbGRzT25seShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RPcHRpb25hbEZpZWxkc09ubHkoKSB7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE9wdGlvbmFsRmllbGRzT25seSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0T3B0aW9uYWxGaWVsZHNPbmx5X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RPcHRpb25hbEZpZWxkc09ubHlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQllURVNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsTmVzdGVkRW51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRPcHRpb25hbE5lc3RlZEVudW0oKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfUFJPVE8yX01FU1NBR0VfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgb3B0aW9uYWxQcm90bzJNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFByb3RvMk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQcm90bzJNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFByb3RvMk1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFByb3RvMk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHJvdG8yTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChvcHRpb25hbEludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ18pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMywgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDQsIG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNSwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKG9wdGlvbmFsSW50MzJfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxTdHJpbmdfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMiwgb3B0aW9uYWxTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoIW9wdGlvbmFsQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoMywgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoNCwgb3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSkgb2JqOwoKICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzIoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxTdHJpbmcoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldE9wdGlvbmFsQnl0ZXMoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IG90aGVyLm9wdGlvbmFsTmVzdGVkRW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxQcm90bzJNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxQcm90bzJNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfUFJPVE8yX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0T3B0aW9uYWxGaWVsZHNPbmx5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0T3B0aW9uYWxGaWVsZHNPbmx5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5Lm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdE9wdGlvbmFsRmllbGRzT25seV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5KHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMl8gPSBvcHRpb25hbEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFN0cmluZ18gPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCeXRlc18gPSBvcHRpb25hbEJ5dGVzXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE5lc3RlZEVudW1fID0gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9IG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxMYXp5TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5KW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRPcHRpb25hbFN0cmluZygpLmlzRW1wdHkoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gb3RoZXIub3B0aW9uYWxTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkgIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5vcHRpb25hbE5lc3RlZEVudW1fICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsUHJvdG8yTWVzc2FnZShvdGhlci5nZXRPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxMYXp5TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpKSB7CiAgICAgICAgICBpZiAoIWdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsU3RyaW5nKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQnl0ZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxCeXRlcygpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkRW51bShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQcm90bzJNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUHJvdG8yTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQcm90bzJNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQcm90bzJNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUHJvdG8yTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsUHJvdG8yTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFByb3RvMk1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9wcm90bzJfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFByb3RvMk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9wdGlvbmFsUHJvdG8yTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBnZXRPcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQcm90bzJNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHJvdG8yTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUHJvdG8yTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxQcm90bzJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbFByb3RvMk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxMYXp5TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxMYXp5TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0T3B0aW9uYWxGaWVsZHNPbmx5KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpmaWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RPcHRpb25hbEZpZWxkc09ubHkpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RPcHRpb25hbEZpZWxkc09ubHkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T3B0aW9uYWxGaWVsZHNPbmx5PgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RPcHRpb25hbEZpZWxkc09ubHk+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0T3B0aW9uYWxGaWVsZHNPbmx5IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9wdGlvbmFsRmllbGRzT25seT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T3B0aW9uYWxGaWVsZHNPbmx5PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdE9wdGlvbmFsRmllbGRzT25seSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZXBlYXRlZEZpZWxkc09ubHlPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5KQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IAogICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdFJlcGVhdGVkRmllbGRzT25seX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZXBlYXRlZEZpZWxkc09ubHkgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5KQogICAgICBUZXN0UmVwZWF0ZWRGaWVsZHNPbmx5T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UmVwZWF0ZWRGaWVsZHNPbmx5Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXBlYXRlZEZpZWxkc09ubHkoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UmVwZWF0ZWRGaWVsZHNPbmx5KCkgewogICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RSZXBlYXRlZEZpZWxkc09ubHkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdFJlcGVhdGVkRmllbGRzT25seV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSID0gMjM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfUFJPVE8yX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IHJlcGVhdGVkUHJvdG8yTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VDb3VudCgpOyBpKyspIHsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZShpKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDE3MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIyLCByZXBlYXRlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMjMsIHJlcGVhdGVkQnl0ZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMTk0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjUsIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI2LCByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcocmVwZWF0ZWRCeXRlc18uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXJlcGVhdGVkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjUsIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjYsIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkpIG9iajsKCiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQnl0ZXNMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9QUk9UTzJfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6ZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5Lm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZEVudW1fID0gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IHJlcGVhdGVkUHJvdG8yTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdfID0gcmVwZWF0ZWRTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQnl0ZXNfID0gcmVwZWF0ZWRCeXRlc187CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RSZXBlYXRlZEZpZWxkc09ubHkpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5KW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG90aGVyLnJlcGVhdGVkSW50MzJfOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZ18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gb3RoZXIucmVwZWF0ZWRCeXRlc187CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCeXRlc18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRQcm90bzJNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkUHJvdG8yTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUNvdW50KCk7IGkrKykgewogICAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2UoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDE2ODogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgKICAgICAgICAgICAgICBjYXNlIDE3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTcwCiAgICAgICAgICAgICAgY2FzZSAxNzg6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGQocyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2ID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5MgogICAgICAgICAgICAgIGNhc2UgMTk0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMgogICAgICAgICAgICAgIGNhc2UgMjEwOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZ18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ18pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFN0cmluZygpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLlByb3RvYnVmTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCeXRlc18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQnl0ZXNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDIzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCeXRlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFJlcGVhdGVkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQnl0ZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQnl0ZXNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCeXRlcyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEJ5dGVzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCeXRlcygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQnl0ZXNfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQnl0ZXMoKSB7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRFbnVtKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZE5lc3RlZEVudW0oKSB7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5maWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZmllbGRfcHJlc2VuY2VfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZFByZXNlbmNlVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4ocmVwZWF0ZWRQcm90bzJNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFByb3RvMk1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJvdG8yTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUHJvdG8yTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJvdG8yTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJvdG8yTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUHJvdG8yTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFByb3RvMk1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcm90bzJNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFByb3RvMk1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRQcm90bzJNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRQcm90bzJNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFByb3RvMk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRQcm90bzJNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYWRkUmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRQcm90bzJNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYWRkUmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZFByb3RvMk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkUHJvdG8yTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkUHJvdG8yTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRQcm90bzJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZFByb3RvMk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpmaWVsZF9wcmVzZW5jZV90ZXN0LlRlc3RSZXBlYXRlZEZpZWxkc09ubHkpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdFJlcGVhdGVkRmllbGRzT25seSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uVGVzdFJlcGVhdGVkRmllbGRzT25seSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXBlYXRlZEZpZWxkc09ubHk+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFJlcGVhdGVkRmllbGRzT25seT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZXBlYXRlZEZpZWxkc09ubHkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVwZWF0ZWRGaWVsZHNPbmx5PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXBlYXRlZEZpZWxkc09ubHk+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRQcmVzZW5jZVRlc3RQcm90by5UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdE9wdGlvbmFsRmllbGRzT25seV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RPcHRpb25hbEZpZWxkc09ubHlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdFJlcGVhdGVkRmllbGRzT25seV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RSZXBlYXRlZEZpZWxkc09ubHlfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi1jb20vZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX3ByZXNlbmNlX3RlcyIgKwogICAgICAidC5wcm90b1wwMjJcMDIzZmllbGRfcHJlc2VuY2VfdGVzdFwwMzJcMDM2Z29vZ2xlL3BybyIgKwogICAgICAidG9idWYvdW5pdHRlc3QucHJvdG9cIlwyMjVcdFxuXDAxNFRlc3RBbGxUeXBlc1wwMjJcMDI2XG4iICsKICAgICAgIlwwMTZvcHRpb25hbF9pbnQzMlwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc3RyaW5nIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFx0XDAyMlwwMjZcblwwMTZvcHRpb25hbF9ieXRlc1wwMzBcMDAzIFwwMDEoXDAxNFwwMjJKXG5cMDI0b3B0aW9uIiArCiAgICAgICJhbF9uZXN0ZWRfZW51bVwwMzBcMDA0IFwwMDEoXDAxNjIsLmZpZWxkX3ByZXNlbmNlX3RlIiArCiAgICAgICJzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bVwwMjJQXG5cMDI3b3B0aW9uYWxfbiIgKwogICAgICAiZXN0ZWRfbWVzc2FnZVwwMzBcMDA1IFwwMDEoXDAxMzIvLmZpZWxkX3ByZXNlbmNlX3RlcyIgKwogICAgICAidC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZVwwMjJAXG5cMDI3b3B0aW9uYWwiICsKICAgICAgIl9wcm90bzJfbWVzc2FnZVwwMzBcMDA2IFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXMiICsKICAgICAgInQuVGVzdFJlcXVpcmVkXDAyMlJcblwwMjVvcHRpb25hbF9sYXp5X21lc3NhZ2VcMDMwIiArCiAgICAgICJcMDA3IFwwMDEoXDAxMzIvLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzIiArCiAgICAgICIuTmVzdGVkTWVzc2FnZUJcMDAyKFwwMDFcMDIyXDAyNVxuXDAxM29uZW9mX2ludDMyXDAzMFwwMTMgXDAwMShcMDA1SCIgKwogICAgICAiXDAwMFwwMjJcMDI2XG5cMDE0b25lb2ZfdWludDMyXDAzMFwwMTQgXDAwMShcckhcMDAwXDAyMlwwMjZcblwwMTRvbmVvZl9zdHJpbiIgKwogICAgICAiZ1wwMzBcciBcMDAxKFx0SFwwMDBcMDIyXDAyNVxuXDAxM29uZW9mX2J5dGVzXDAzMFwwMTYgXDAwMShcMDE0SFwwMDBcMDIySVxuXDAyMW9uZW8iICsKICAgICAgImZfbmVzdGVkX2VudW1cMDMwXDAxNyBcMDAxKFwwMTYyLC5maWVsZF9wcmVzZW5jZV90ZXMiICsKICAgICAgInQuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW1IXDAwMFwwMjJPXG5cMDI0b25lb2ZfbmVzIiArCiAgICAgICJ0ZWRfbWVzc2FnZVwwMzBcMDIwIFwwMDEoXDAxMzIvLmZpZWxkX3ByZXNlbmNlX3Rlc3QuIiArCiAgICAgICJUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUhcMDAwXDAyMj9cblwwMjRvbmVvZl9wciIgKwogICAgICAib3RvMl9tZXNzYWdlXDAzMFwwMjEgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVCIgKwogICAgICAiZXN0UmVxdWlyZWRIXDAwMFwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXDAyNSBcMDAzKFwwMDVcMDIyXDAyN1xuIiArCiAgICAgICJcMDE3cmVwZWF0ZWRfc3RyaW5nXDAzMFwwMjYgXDAwMyhcdFwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfYnl0ZXMiICsKICAgICAgIlwwMzBcMDI3IFwwMDMoXDAxNFwwMjJKXG5cMDI0cmVwZWF0ZWRfbmVzdGVkX2VudW1cMDMwXDAzMCBcMDAzKFwwMTYyLC5mIiArCiAgICAgICJpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVuIiArCiAgICAgICJ1bVwwMjJQXG5cMDI3cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VcMDMwXDAzMSBcMDAzKFwwMTMyLy5maSIgKwogICAgICAiZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lcyIgKwogICAgICAic2FnZVwwMjJAXG5cMDI3cmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2VcMDMwXDAzMiBcMDAzKFwwMTMyXDAzNy4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZFwwMjJMXG5cMDIycGFja2VkIiArCiAgICAgICJfbmVzdGVkX2VudW1cMDMwXDAzMyBcMDAzKFwwMTYyLC5maWVsZF9wcmVzZW5jZV90ZXN0IiArCiAgICAgICIuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW1CXDAwMlwwMjBcMDAxXDAzMlwwMzZcblxyTmVzdGVkTWUiICsKICAgICAgInNzYWdlXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAxKFwwMDVcIlwnXG5cbk5lc3RlZEVudW1cMDIyXDAwN1xuXDAwM0ZPIiArCiAgICAgICJPXDAyMFwwMDBcMDIyXDAwN1xuXDAwM0JBUlwwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVpcMDIwXDAwMkJcclxuXDAxM29uZW9mX2ZpZWxkXCJcMjI1XDAwM1xuIiArCiAgICAgICJcMDI2VGVzdE9wdGlvbmFsRmllbGRzT25seVwwMjJcMDI2XG5cMDE2b3B0aW9uYWxfaW50MyIgKwogICAgICAiMlwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc3RyaW5nXDAzMFwwMDIgXDAwMShcdFwwMjJcMDI2XG5cMDE2b3B0aSIgKwogICAgICAib25hbF9ieXRlc1wwMzBcMDAzIFwwMDEoXDAxNFwwMjJKXG5cMDI0b3B0aW9uYWxfbmVzdGVkX2VudW0iICsKICAgICAgIlwwMzBcMDA0IFwwMDEoXDAxNjIsLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGUiICsKICAgICAgInMuTmVzdGVkRW51bVwwMjJQXG5cMDI3b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VcMDMwIiArCiAgICAgICJcMDA1IFwwMDEoXDAxMzIvLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzIiArCiAgICAgICIuTmVzdGVkTWVzc2FnZVwwMjJAXG5cMDI3b3B0aW9uYWxfcHJvdG8yX21lc3NhZyIgKwogICAgICAiZVwwMzBcMDA2IFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCIgKwogICAgICAiXDAyMlJcblwwMjVvcHRpb25hbF9sYXp5X21lc3NhZ2VcMDMwXDAwNyBcMDAxKFwwMTMyLy5maWVsZF8iICsKICAgICAgInByZXNlbmNlX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UiICsKICAgICAgIkJcMDAyKFwwMDFcIlwzMDFcMDAyXG5cMDI2VGVzdFJlcGVhdGVkRmllbGRzT25seVwwMjJcMDI2XG5cMDE2cmVwZWEiICsKICAgICAgInRlZF9pbnQzMlwwMzBcMDI1IFwwMDMoXDAwNVwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfc3RyaW5nXDAzMFwwMjYgXDAwMyhcdCIgKwogICAgICAiXDAyMlwwMjZcblwwMTZyZXBlYXRlZF9ieXRlc1wwMzBcMDI3IFwwMDMoXDAxNFwwMjJKXG5cMDI0cmVwZWF0ZWRfbmVzIiArCiAgICAgICJ0ZWRfZW51bVwwMzBcMDMwIFwwMDMoXDAxNjIsLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzIiArCiAgICAgICJ0QWxsVHlwZXMuTmVzdGVkRW51bVwwMjJQXG5cMDI3cmVwZWF0ZWRfbmVzdGVkXyIgKwogICAgICAibWVzc2FnZVwwMzBcMDMxIFwwMDMoXDAxMzIvLmZpZWxkX3ByZXNlbmNlX3Rlc3QuVGVzdCIgKwogICAgICAiQWxsVHlwZXMuTmVzdGVkTWVzc2FnZVwwMjJAXG5cMDI3cmVwZWF0ZWRfcHJvdG8iICsKICAgICAgIjJfbWVzc2FnZVwwMzBcMDMyIFwwMDMoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3QiICsKICAgICAgIlJlcXVpcmVkQi1cblwwMjNjb20uZ29vZ2xlLnByb3RvYnVmQlwwMjZGaWVsZFByIiArCiAgICAgICJlc2VuY2VUZXN0UHJvdG9iXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50MzIiLCAiT3B0aW9uYWxTdHJpbmciLCAiT3B0aW9uYWxCeXRlcyIsICJPcHRpb25hbE5lc3RlZEVudW0iLCAiT3B0aW9uYWxOZXN0ZWRNZXNzYWdlIiwgIk9wdGlvbmFsUHJvdG8yTWVzc2FnZSIsICJPcHRpb25hbExhenlNZXNzYWdlIiwgIk9uZW9mSW50MzIiLCAiT25lb2ZVaW50MzIiLCAiT25lb2ZTdHJpbmciLCAiT25lb2ZCeXRlcyIsICJPbmVvZk5lc3RlZEVudW0iLCAiT25lb2ZOZXN0ZWRNZXNzYWdlIiwgIk9uZW9mUHJvdG8yTWVzc2FnZSIsICJSZXBlYXRlZEludDMyIiwgIlJlcGVhdGVkU3RyaW5nIiwgIlJlcGVhdGVkQnl0ZXMiLCAiUmVwZWF0ZWROZXN0ZWRFbnVtIiwgIlJlcGVhdGVkTmVzdGVkTWVzc2FnZSIsICJSZXBlYXRlZFByb3RvMk1lc3NhZ2UiLCAiUGFja2VkTmVzdGVkRW51bSIsICJPbmVvZkZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdE9wdGlvbmFsRmllbGRzT25seV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RPcHRpb25hbEZpZWxkc09ubHlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0T3B0aW9uYWxGaWVsZHNPbmx5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbEludDMyIiwgIk9wdGlvbmFsU3RyaW5nIiwgIk9wdGlvbmFsQnl0ZXMiLCAiT3B0aW9uYWxOZXN0ZWRFbnVtIiwgIk9wdGlvbmFsTmVzdGVkTWVzc2FnZSIsICJPcHRpb25hbFByb3RvMk1lc3NhZ2UiLCAiT3B0aW9uYWxMYXp5TWVzc2FnZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX2ZpZWxkX3ByZXNlbmNlX3Rlc3RfVGVzdFJlcGVhdGVkRmllbGRzT25seV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19maWVsZF9wcmVzZW5jZV90ZXN0X1Rlc3RSZXBlYXRlZEZpZWxkc09ubHlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfZmllbGRfcHJlc2VuY2VfdGVzdF9UZXN0UmVwZWF0ZWRGaWVsZHNPbmx5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXBlYXRlZEludDMyIiwgIlJlcGVhdGVkU3RyaW5nIiwgIlJlcGVhdGVkQnl0ZXMiLCAiUmVwZWF0ZWROZXN0ZWRFbnVtIiwgIlJlcGVhdGVkTmVzdGVkTWVzc2FnZSIsICJSZXBlYXRlZFByb3RvMk1lc3NhZ2UiLCB9KTsKICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEA32hc1qOqAwCjqgMALQAAAGNvbS9nb29nbGUvcHJvdG9idWYvUGFja2VkRmllbGRUZXN0UHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9wYWNrZWRfZmllbGRfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKCnB1YmxpYyBmaW5hbCBjbGFzcyBQYWNrZWRGaWVsZFRlc3RQcm90byB7CiAgcHJpdmF0ZSBQYWNrZWRGaWVsZFRlc3RQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkSW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkVWludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZFVpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkU2ludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZFNpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRTZml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldFJlcGVhdGVkRmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRG91YmxlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldFJlcGVhdGVkQm9vbExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RBbGxUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RBbGxUeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RBbGxUeXBlcygpIHsKICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEFsbFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIE5lc3RlZEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMiksCiAgICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9WQUxVRSA9IDI7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBWjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5lc3RlZEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgICAgIHJldHVybiBVTlJFQ09HTklaRUQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSkKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVIgPSAzMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkVWludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDMyX0ZJRUxEX05VTUJFUiA9IDM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TSU5UNjRfRklFTERfTlVNQkVSID0gMzY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSID0gMzg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNmaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gNDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSID0gNDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcmVwZWF0ZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ET1VCTEVfRklFTERfTlVNQkVSID0gNDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHJlcGVhdGVkRG91YmxlXyA9CiAgICAgICAgZW1wdHlEb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQk9PTF9GSUVMRF9OVU1CRVIgPSA0MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbF8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gNTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI1MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI1OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NE5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjY2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNzQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyODIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzJOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI5MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NE5vVGFnKHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyOTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhyZXBlYXRlZEZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzA2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0Tm9UYWcocmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzE0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyTm9UYWcocmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzIyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcocmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdE5vVGFnKHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzOCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRG91YmxlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZU5vVGFnKHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJvb2xMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM0Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNDEwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcocmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcocmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZU5vVGFnKHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1yZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZsb2F0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEJvb2xMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWROZXN0ZWRFbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZEVudW1fID0gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDMyXyA9IHJlcGVhdGVkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50NjRfID0gcmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDMyXyA9IHJlcGVhdGVkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRVaW50NjRfID0gcmVwZWF0ZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQzMl8gPSByZXBlYXRlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ludDY0XyA9IHJlcGVhdGVkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQzMl8gPSByZXBlYXRlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGaXhlZDY0XyA9IHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQzMl8gPSByZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNmaXhlZDY0XyA9IHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRmxvYXRfID0gcmVwZWF0ZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRG91YmxlXyA9IHJlcGVhdGVkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQm9vbF8gPSByZXBlYXRlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5yZXBlYXRlZEludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBvdGhlci5yZXBlYXRlZEludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFVpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG90aGVyLnJlcGVhdGVkVWludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gb3RoZXIucmVwZWF0ZWRTaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkRml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZEZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gb3RoZXIucmVwZWF0ZWRGbG9hdF87CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gb3RoZXIucmVwZWF0ZWREb3VibGVfOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBvdGhlci5yZXBlYXRlZEJvb2xfOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQm9vbF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMjQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0OAogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1NjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1NgogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU4CiAgICAgICAgICAgICAgY2FzZSAyNjQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY0CiAgICAgICAgICAgICAgY2FzZSAyNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NgogICAgICAgICAgICAgIGNhc2UgMjcyOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjcyCiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzQKICAgICAgICAgICAgICBjYXNlIDI4MDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODAKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyODg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODgKICAgICAgICAgICAgICBjYXNlIDI5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMzAxOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwMQogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA1OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA1CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNgogICAgICAgICAgICAgIGNhc2UgMzE3OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNwogICAgICAgICAgICAgIGNhc2UgMzE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNAogICAgICAgICAgICAgIGNhc2UgMzIxOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIxCiAgICAgICAgICAgICAgY2FzZSAzMjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMgogICAgICAgICAgICAgIGNhc2UgMzMzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzMKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMAogICAgICAgICAgICAgIGNhc2UgMzM3OiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzNwogICAgICAgICAgICAgIGNhc2UgMzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ0OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ0CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgNDA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MDgKICAgICAgICAgICAgICBjYXNlIDQxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDY0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFVpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDMyKCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRVaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkVWludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDMyKCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNmaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ZpeGVkNjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmxvYXQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZsb2F0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpIHsKICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZERvdWJsZV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZERvdWJsZSgpIHsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJvb2woCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRCb29sXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCb29sKCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bShjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZE5lc3RlZEVudW0oKSB7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEFsbFR5cGVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEFsbFR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwYWNrZWRfZmllbGRfdGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldFJlcGVhdGVkRmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRG91YmxlLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldFJlcGVhdGVkQm9vbExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcGFja2VkX2ZpZWxkX3Rlc3QuVGVzdFVucGFja2VkVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0VW5wYWNrZWRUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwYWNrZWRfZmllbGRfdGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgVGVzdFVucGFja2VkVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RVbnBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RVbnBhY2tlZFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFVucGFja2VkVHlwZXMoKSB7CiAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RVbnBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFVpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkVWludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDMyX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TSU5UNjRfRklFTERfTlVNQkVSID0gNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNmaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHJlcGVhdGVkRmxvYXRfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHJlcGVhdGVkRG91YmxlXyA9CiAgICAgICAgZW1wdHlEb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRG91YmxlLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRG91YmxlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0JPT0xfRklFTERfTlVNQkVSID0gMTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCByZXBlYXRlZEJvb2xfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQm9vbENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCByZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgyLCByZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigzLCByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoNSwgcmVwZWF0ZWRTaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoNiwgcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoNywgcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoOCwgcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoOSwgcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTAsIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgxMSwgcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEyLCByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQm9vbF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEzLCByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTQsIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkVWludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMpIG9iajsKCiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQm9vbExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZE5lc3RlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwYWNrZWRfZmllbGRfdGVzdC5UZXN0VW5wYWNrZWRUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnBhY2tlZF9maWVsZF90ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdFVucGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkRW51bV8gPSByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDY0XyA9IHJlcGVhdGVkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQzMl8gPSByZXBlYXRlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDY0XyA9IHJlcGVhdGVkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50MzJfID0gcmVwZWF0ZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQ2NF8gPSByZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQ2NF8gPSByZXBlYXRlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkMzJfID0gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQ2NF8gPSByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZsb2F0XyA9IHJlcGVhdGVkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZERvdWJsZV8gPSByZXBlYXRlZERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJvb2xfID0gcmVwZWF0ZWRCb29sXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5yZXBlYXRlZEludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBvdGhlci5yZXBlYXRlZEludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFVpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG90aGVyLnJlcGVhdGVkVWludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gb3RoZXIucmVwZWF0ZWRTaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkRml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZEZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gb3RoZXIucmVwZWF0ZWRGbG9hdF87CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gb3RoZXIucmVwZWF0ZWREb3VibGVfOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBvdGhlci5yZXBlYXRlZEJvb2xfOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQm9vbF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRVSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwCiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDYxOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYxCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjU6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NQogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3NzogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NwogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgxOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTM6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzCiAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwCiAgICAgICAgICAgICAgY2FzZSA5NzogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZSh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NwogICAgICAgICAgICAgIGNhc2UgOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgICBjYXNlIDEwNDogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNAogICAgICAgICAgICAgIGNhc2UgMTA2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbihpbnB1dC5yZWFkQm9vbCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDYKICAgICAgICAgICAgICBjYXNlIDExMjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEyCiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQzMigpIHsKICAgICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDY0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDMyKCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZpeGVkMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ZpeGVkNjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmxvYXQoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmxvYXQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRmxvYXQoKSB7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZERvdWJsZV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWREb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWREb3VibGUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWREb3VibGUoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQm9vbENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQm9vbChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCb29sKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCb29sKCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0oY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuUGFja2VkRmllbGRUZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTmVzdGVkRW51bSgpIHsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnBhY2tlZF9maWVsZF90ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wYWNrZWRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cGFja2VkX2ZpZWxkX3Rlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnBhY2tlZF9maWVsZF90ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYWNrZWRGaWVsZFRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VW5wYWNrZWRUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhY2tlZEZpZWxkVGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3BhY2tlZF9maWVsZF90ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3BhY2tlZF9maWVsZF90ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3BhY2tlZF9maWVsZF90ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4rY29tL2dvb2dsZS9wcm90b2J1Zi9wYWNrZWRfZmllbGRfdGVzdC4iICsKICAgICAgInByb3RvXDAyMlwwMjFwYWNrZWRfZmllbGRfdGVzdFwiXDMwN1wwMDNcblwwMTRUZXN0QWxsVHlwZSIgKwogICAgICAic1wwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXDAzNyBcMDAzKFwwMDVcMDIyXDAyNlxuXDAxNnJlcGVhdGVkX2luIiArCiAgICAgICJ0NjRcMDMwICBcMDAzKFwwMDNcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3VpbnQzMlwwMzAhIFwwMDMoXHJcMDIyXDAyN1xuXDAxN3JlIiArCiAgICAgICJwZWF0ZWRfdWludDY0XDAzMFwiIFwwMDMoXDAwNFwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfc2ludDMyXDAzMCMiICsKICAgICAgIiBcMDAzKFwwMjFcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3NpbnQ2NFwwMzAkIFwwMDMoXDAyMlwwMjJcMDMwXG5cMDIwcmVwZWF0ZSIgKwogICAgICAiZF9maXhlZDMyXDAzMCUgXDAwMyhcMDA3XDAyMlwwMzBcblwwMjByZXBlYXRlZF9maXhlZDY0XDAzMCYgXDAwMygiICsKICAgICAgIlwwMDZcMDIyXDAzMVxuXDAyMXJlcGVhdGVkX3NmaXhlZDMyXDAzMFwnIFwwMDMoXDAxN1wwMjJcMDMxXG5cMDIxcmVwZWF0ZWQiICsKICAgICAgIl9zZml4ZWQ2NFwwMzAoIFwwMDMoXDAyMFwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfZmxvYXRcMDMwKSBcMDAzKFwwMDJcMDIyIiArCiAgICAgICJcMDI3XG5cMDE3cmVwZWF0ZWRfZG91YmxlXDAzMCogXDAwMyhcMDAxXDAyMlwwMjVcblxycmVwZWF0ZWRfYm9vIiArCiAgICAgICJsXDAzMCsgXDAwMyhcMDEwXDAyMkhcblwwMjRyZXBlYXRlZF9uZXN0ZWRfZW51bVwwMzAzIFwwMDMoXDAxNjIqLiIgKwogICAgICAicGFja2VkX2ZpZWxkX3Rlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudSIgKwogICAgICAibVwiXCdcblxuTmVzdGVkRW51bVwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDBcMDIyXDAwN1xuXDAwM0JBUlwwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVoiICsKICAgICAgIlwwMjBcMDAyXCJcMzMzXDAwM1xuXDAyMVRlc3RVbnBhY2tlZFR5cGVzXDAyMlwwMzJcblwwMTZyZXBlYXRlZF9pbnQiICsKICAgICAgIjMyXDAzMFwwMDEgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMFwwMjJcMDMyXG5cMDE2cmVwZWF0ZWRfaW50NjRcMDMwXDAwMiBcMDAzKFwwMDNCXDAwMlwwMjBcMDAwIiArCiAgICAgICJcMDIyXDAzM1xuXDAxN3JlcGVhdGVkX3VpbnQzMlwwMzBcMDAzIFwwMDMoXHJCXDAwMlwwMjBcMDAwXDAyMlwwMzNcblwwMTdyZXBlYXRlIiArCiAgICAgICJkX3VpbnQ2NFwwMzBcMDA0IFwwMDMoXDAwNEJcMDAyXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3JlcGVhdGVkX3NpbnQzMlwwMzBcMDA1ICIgKwogICAgICAiXDAwMyhcMDIxQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfc2ludDY0XDAzMFwwMDYgXDAwMyhcMDIyQlwwMDJcMDIwXDAwMFwwMjJcMDM0XG5cMDIwIiArCiAgICAgICJyZXBlYXRlZF9maXhlZDMyXDAzMFwwMDcgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMFwwMjJcMDM0XG5cMDIwcmVwZWF0ZWRfZiIgKwogICAgICAiaXhlZDY0XDAzMFwwMTAgXDAwMyhcMDA2QlwwMDJcMDIwXDAwMFwwMjJcMDM1XG5cMDIxcmVwZWF0ZWRfc2ZpeGVkMzJcMDMwXHQgIiArCiAgICAgICJcMDAzKFwwMTdCXDAwMlwwMjBcMDAwXDAyMlwwMzVcblwwMjFyZXBlYXRlZF9zZml4ZWQ2NFwwMzBcbiBcMDAzKFwwMjBCXDAwMlwwMjBcMDAwXDAyMlwwMzIiICsKICAgICAgIlxuXDAxNnJlcGVhdGVkX2Zsb2F0XDAzMFwwMTMgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfZCIgKwogICAgICAib3VibGVcMDMwXDAxNCBcMDAzKFwwMDFCXDAwMlwwMjBcMDAwXDAyMlwwMzFcblxycmVwZWF0ZWRfYm9vbFwwMzBcciBcMDAzKFwwMTBCXDAwMiIgKwogICAgICAiXDAyMFwwMDBcMDIyTFxuXDAyNHJlcGVhdGVkX25lc3RlZF9lbnVtXDAzMFwwMTYgXDAwMyhcMDE2MioucGFja2UiICsKICAgICAgImRfZmllbGRfdGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bUJcMDAyXDAyMFwwMDAiICsKICAgICAgIkIrXG5cMDIzY29tLmdvb2dsZS5wcm90b2J1ZkJcMDI0UGFja2VkRmllbGRUZXN0IiArCiAgICAgICJQcm90b2JcMDA2cHJvdG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcGFja2VkX2ZpZWxkX3Rlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3BhY2tlZF9maWVsZF90ZXN0X1Rlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcGVhdGVkSW50MzIiLCAiUmVwZWF0ZWRJbnQ2NCIsICJSZXBlYXRlZFVpbnQzMiIsICJSZXBlYXRlZFVpbnQ2NCIsICJSZXBlYXRlZFNpbnQzMiIsICJSZXBlYXRlZFNpbnQ2NCIsICJSZXBlYXRlZEZpeGVkMzIiLCAiUmVwZWF0ZWRGaXhlZDY0IiwgIlJlcGVhdGVkU2ZpeGVkMzIiLCAiUmVwZWF0ZWRTZml4ZWQ2NCIsICJSZXBlYXRlZEZsb2F0IiwgIlJlcGVhdGVkRG91YmxlIiwgIlJlcGVhdGVkQm9vbCIsICJSZXBlYXRlZE5lc3RlZEVudW0iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wYWNrZWRfZmllbGRfdGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAh3QQ76z+AACs/gAAOQAAAGNvbS9nb29nbGUvcHJvdG9idWYvUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKCnB1YmxpYyBmaW5hbCBjbGFzcyBQcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90byB7CiAgcHJpdmF0ZSBQcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW19CiAgICovCiAgcHVibGljIGVudW0gUHJvdG8yVGVzdEVudW0KICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5aRVJPID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIFpFUk8oMCksCiAgICAvKioKICAgICAqIDxjb2RlPk9ORSA9IDE7PC9jb2RlPgogICAgICovCiAgICBPTkUoMSksCiAgICAvKioKICAgICAqIDxjb2RlPlRXTyA9IDI7PC9jb2RlPgogICAgICovCiAgICBUV08oMiksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5aRVJPID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFpFUk9fVkFMVUUgPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5PTkUgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FX1ZBTFVFID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+VFdPID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRXT19WQUxVRSA9IDI7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgUHJvdG8yVGVzdEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBQcm90bzJUZXN0RW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBaRVJPOwogICAgICAgIGNhc2UgMTogcmV0dXJuIE9ORTsKICAgICAgICBjYXNlIDI6IHJldHVybiBUV087CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8UHJvdG8yVGVzdEVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIFByb3RvMlRlc3RFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFByb3RvMlRlc3RFbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIFByb3RvMlRlc3RFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gUHJvdG8yVGVzdEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3RvMlRlc3RFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBQcm90bzJUZXN0RW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIFByb3RvMlRlc3RFbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW0pCiAgfQoKICAvKioKICAgKiA8cHJlPgogICAqIEFuIGVudW0gY29udGFpbmluZyBhIHN1YnNldCBvZiB0aGUgdmFsdWVzIG9mIFByb3RvMlRlc3RFbnVtLCB0byB0ZXN0CiAgICogcGFyc2luZyB1bmtub3duIHBhY2tlZCBlbnVtIHZhbHVlcwogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW1TdWJzZXR9CiAgICovCiAgcHVibGljIGVudW0gUHJvdG8yVGVzdEVudW1TdWJzZXQKICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5URVNURU5VTV9TVUJTRVRfWkVSTyA9IDA7PC9jb2RlPgogICAgICovCiAgICBURVNURU5VTV9TVUJTRVRfWkVSTygwKSwKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5vIGVudW0gdmFsdWUgd2l0aCBudW1iZXIgMi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPlRFU1RFTlVNX1NVQlNFVF9PTkUgPSAxOzwvY29kZT4KICAgICAqLwogICAgVEVTVEVOVU1fU1VCU0VUX09ORSgxKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPlRFU1RFTlVNX1NVQlNFVF9aRVJPID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RFTlVNX1NVQlNFVF9aRVJPX1ZBTFVFID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5vIGVudW0gdmFsdWUgd2l0aCBudW1iZXIgMi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPlRFU1RFTlVNX1NVQlNFVF9PTkUgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVEVOVU1fU1VCU0VUX09ORV9WQUxVRSA9IDE7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgUHJvdG8yVGVzdEVudW1TdWJzZXQgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBQcm90bzJUZXN0RW51bVN1YnNldCBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBURVNURU5VTV9TVUJTRVRfWkVSTzsKICAgICAgICBjYXNlIDE6IHJldHVybiBURVNURU5VTV9TVUJTRVRfT05FOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFByb3RvMlRlc3RFbnVtU3Vic2V0PgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBQcm90bzJUZXN0RW51bVN1YnNldD4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxQcm90bzJUZXN0RW51bVN1YnNldD4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBQcm90bzJUZXN0RW51bVN1YnNldCBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIFByb3RvMlRlc3RFbnVtU3Vic2V0LmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICB9CiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgxKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcm90bzJUZXN0RW51bVN1YnNldFtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgIHB1YmxpYyBzdGF0aWMgUHJvdG8yVGVzdEVudW1TdWJzZXQgdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBQcm90bzJUZXN0RW51bVN1YnNldChpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtU3Vic2V0KQogIH0KCiAgcHVibGljIGludGVyZmFjZSBQcm90bzJFbnVtTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJFbnVtTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bSByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkUGFja2VkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bT4gZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW0gcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFBhY2tlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFBhY2tlZEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW0gcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkUGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW0gZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMkVudW1NZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvdG8yRW51bU1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yRW51bU1lc3NhZ2UpCiAgICAgIFByb3RvMkVudW1NZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQcm90bzJFbnVtTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzJFbnVtTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvMkVudW1NZXNzYWdlKCkgewogICAgICByZXBlYXRlZFBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvMkVudW1NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXNfUHJvdG8yRW51bU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRQYWNrZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtPiByZXBlYXRlZFBhY2tlZEVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtLlpFUk8gOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW0gcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtPiBnZXRSZXBlYXRlZFBhY2tlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bT4ocmVwZWF0ZWRQYWNrZWRFbnVtXywgcmVwZWF0ZWRQYWNrZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW0gcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFBhY2tlZEVudW1fLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtIHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bSBnZXRSZXBlYXRlZFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFBhY2tlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkUGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZFBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGdldFJlcGVhdGVkUGFja2VkRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMTApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkUGFja2VkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRQYWNrZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhyZXBlYXRlZFBhY2tlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRQYWNrZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRQYWNrZWRFbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAxOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cmVwZWF0ZWRQYWNrZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFyZXBlYXRlZFBhY2tlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZFBhY2tlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRSZXBlYXRlZFBhY2tlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1BBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZFBhY2tlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJFbnVtTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMkVudW1NZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXNfUHJvdG8yRW51bU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXNfUHJvdG8yRW51bU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkUGFja2VkRW51bV8gPSByZXBlYXRlZFBhY2tlZEVudW1fOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRQYWNrZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fID0gb3RoZXIucmVwZWF0ZWRQYWNrZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkUGFja2VkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkUGFja2VkRW51bV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkUGFja2VkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkUGFja2VkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtIHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bT4gZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtPihyZXBlYXRlZFBhY2tlZEVudW1fLCByZXBlYXRlZFBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bSByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRQYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFBhY2tlZEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRQYWNrZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bSByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkUGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bSBnZXRSZXBlYXRlZFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkUGFja2VkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRQYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtIHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRQYWNrZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRQYWNrZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW0gcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRQYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRQYWNrZWRFbnVtKGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtIHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFBhY2tlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtIHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkUGFja2VkRW51bSgpIHsKICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJFbnVtTWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yRW51bU1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJFbnVtTWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzJFbnVtTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMkVudW1NZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yRW51bU1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yRW51bU1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBQcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW1TdWJzZXQgcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFBhY2tlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQ+IGdldFJlcGVhdGVkUGFja2VkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtU3Vic2V0IHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRQYWNrZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtU3Vic2V0IHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtU3Vic2V0IGdldFJlcGVhdGVkUGFja2VkRW51bShpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgbWVzc2FnZXMgZm9yIHBhY2tlZCBlbnVtLCB3aXRoIGlkZW50aWNhbCBmaWVsZCBudW1iZXIgYXMKICAgKiBQcm90bzJNZXNzYWdlLCB0byB0ZXN0IHBhcnNpbmcgdW5rbm93biBwYWNrZWQgZW51bXMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0KQogICAgICBQcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBQcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0KCkgewogICAgICByZXBlYXRlZFBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXNfUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1BBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkUGFja2VkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldD4gcmVwZWF0ZWRQYWNrZWRFbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldD4oKSB7CiAgICAgICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQgY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtU3Vic2V0IHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldC5URVNURU5VTV9TVUJTRVRfWkVSTyA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bVN1YnNldCByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkUGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQ+IGdldFJlcGVhdGVkUGFja2VkRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtU3Vic2V0PihyZXBlYXRlZFBhY2tlZEVudW1fLCByZXBlYXRlZFBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bVN1YnNldCByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkUGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFBhY2tlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUGFja2VkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW1TdWJzZXQgcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkUGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtU3Vic2V0IGdldFJlcGVhdGVkUGFja2VkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUGFja2VkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRQYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkUGFja2VkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRQYWNrZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHJlcGVhdGVkUGFja2VkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZFBhY2tlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFBhY2tlZEVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDE7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1yZXBlYXRlZFBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0KSBvYmo7CgogICAgICBpZiAoIXJlcGVhdGVkUGFja2VkRW51bV8uZXF1YWxzKG90aGVyLnJlcGVhdGVkUGFja2VkRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFJlcGVhdGVkUGFja2VkRW51bUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkUGFja2VkRW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgbWVzc2FnZXMgZm9yIHBhY2tlZCBlbnVtLCB3aXRoIGlkZW50aWNhbCBmaWVsZCBudW1iZXIgYXMKICAgICAqIFByb3RvMk1lc3NhZ2UsIHRvIHRlc3QgcGFyc2luZyB1bmtub3duIHBhY2tlZCBlbnVtcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvMl91bmtub3duX2VudW1fdmFsdWVzX1Byb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0KHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkUGFja2VkRW51bV8gPSByZXBlYXRlZFBhY2tlZEVudW1fOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkUGFja2VkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRQYWNrZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXyA9IG90aGVyLnJlcGVhdGVkUGFja2VkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZFBhY2tlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldC5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldC5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFBhY2tlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFBhY2tlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZFBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bVN1YnNldCByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRQYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQ+IGdldFJlcGVhdGVkUGFja2VkRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldD4ocmVwZWF0ZWRQYWNrZWRFbnVtXywgcmVwZWF0ZWRQYWNrZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW1TdWJzZXQgcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkUGFja2VkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkUGFja2VkRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yVGVzdEVudW1TdWJzZXQgcmVwZWF0ZWRfcGFja2VkX2VudW0gPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQgZ2V0UmVwZWF0ZWRQYWNrZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFBhY2tlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkUGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bVN1YnNldCByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkUGFja2VkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkUGFja2VkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5Qcm90bzJUZXN0RW51bVN1YnNldCB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3RvMlRlc3RFbnVtU3Vic2V0IHJlcGVhdGVkX3BhY2tlZF9lbnVtID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkUGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUGFja2VkRW51bShjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtU3Vic2V0IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFBhY2tlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bVN1YnNldCByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRQYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRQYWNrZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMlRlc3RFbnVtU3Vic2V0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yVGVzdEVudW1TdWJzZXQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkUGFja2VkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlcy5Qcm90bzJUZXN0RW51bVN1YnNldCByZXBlYXRlZF9wYWNrZWRfZW51bSA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFBhY2tlZEVudW0oKSB7CiAgICAgICAgcmVwZWF0ZWRQYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXMuUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvMlVua25vd25FbnVtVmFsdWVzVGVzdFByb3RvLlByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQ+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8uUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXNfUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0X2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG40Y29tL2dvb2dsZS9wcm90b2J1Zi9wcm90bzJfdW5rbm93bl9lbnUiICsKICAgICAgIm1fdmFsdWVzLnByb3RvXDAyMlwwMzJwcm90bzJfdW5rbm93bl9lbnVtX3ZhbHUiICsKICAgICAgImVzXCJhXG5cMDIxUHJvdG8yRW51bU1lc3NhZ2VcMDIyTFxuXDAyNHJlcGVhdGVkX3BhY2siICsKICAgICAgImVkX2VudW1cMDMwXDAwMSBcMDAzKFwwMTYyKi5wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHUiICsKICAgICAgImVzLlByb3RvMlRlc3RFbnVtQlwwMDJcMDIwXDAwMVwidVxuXDAzN1Byb3RvMkVudW1NZXNzYSIgKwogICAgICAiZ2VXaXRoRW51bVN1YnNldFwwMjJSXG5cMDI0cmVwZWF0ZWRfcGFja2VkX2VudW0iICsKICAgICAgIlwwMzBcMDAxIFwwMDMoXDAxNjIwLnByb3RvMl91bmtub3duX2VudW1fdmFsdWVzLlByb3QiICsKICAgICAgIm8yVGVzdEVudW1TdWJzZXRCXDAwMlwwMjBcMDAxKixcblwwMTZQcm90bzJUZXN0RW51bVwwMjJcMDEwIiArCiAgICAgICJcblwwMDRaRVJPXDAyMFwwMDBcMDIyXDAwN1xuXDAwM09ORVwwMjBcMDAxXDAyMlwwMDdcblwwMDNUV09cMDIwXDAwMipJXG5cMDI0UHJvdG8yVGVzdCIgKwogICAgICAiRW51bVN1YnNldFwwMjJcMDMwXG5cMDI0VEVTVEVOVU1fU1VCU0VUX1pFUk9cMDIwXDAwMFwwMjJcMDI3XG5cMDIzIiArCiAgICAgICJURVNURU5VTV9TVUJTRVRfT05FXDAyMFwwMDFCN1xuXDAyM2NvbS5nb29nbGUucHJvdCIgKwogICAgICAib2J1ZkIgUHJvdG8yVW5rbm93bkVudW1WYWx1ZXNUZXN0UHJvdG8iCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVwZWF0ZWRQYWNrZWRFbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Vua25vd25fZW51bV92YWx1ZXNfUHJvdG8yRW51bU1lc3NhZ2VXaXRoRW51bVN1YnNldF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdW5rbm93bl9lbnVtX3ZhbHVlc19Qcm90bzJFbnVtTWVzc2FnZVdpdGhFbnVtU3Vic2V0X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl91bmtub3duX2VudW1fdmFsdWVzX1Byb3RvMkVudW1NZXNzYWdlV2l0aEVudW1TdWJzZXRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcGVhdGVkUGFja2VkRW51bSIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAGtX9oqCKCwCgigsAMAAAAGNvbS9nb29nbGUvcHJvdG9idWYvVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1ZjsKCnB1YmxpYyBmaW5hbCBjbGFzcyBUZXN0QmFkSWRlbnRpZmllcnNQcm90byB7CiAgcHJpdmF0ZSBUZXN0QmFkSWRlbnRpZmllcnNQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuaW50NjRGaWVsZENvdW50KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuaW50NjRGaWVsZExpc3QpOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBqYXZhLmxhbmcuT2JqZWN0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNsYXNzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNsYXNzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNDbGFzc18oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2xhc3MgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNsYXNzLgogICAgICovCiAgICBib29sZWFuIGdldENsYXNzXygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9pbnN0YW5jZV9mb3JfdHlwZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2luc3RhbmNlX2Zvcl90eXBlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlLgogICAgICovCiAgICBib29sZWFuIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBwYXJzZXJfZm9yX3R5cGUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGFyc2VyRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUGFyc2VyRm9yVHlwZV8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcGFyc2VyX2Zvcl90eXBlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwYXJzZXJGb3JUeXBlLgogICAgICovCiAgICBib29sZWFuIGdldFBhcnNlckZvclR5cGVfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzZXJpYWxpemVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU2VyaWFsaXplZFNpemVfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZF9zaXplID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkU2l6ZS4KICAgICAqLwogICAgYm9vbGVhbiBnZXRTZXJpYWxpemVkU2l6ZV8oKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYWxsX2ZpZWxkcyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbGxGaWVsZHMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0FsbEZpZWxkc18oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBhbGxfZmllbGRzID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhbGxGaWVsZHMuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0QWxsRmllbGRzXygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yX2Zvcl90eXBlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlc2NyaXB0b3JGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yX2Zvcl90eXBlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZXNjcmlwdG9yRm9yVHlwZS4KICAgICAqLwogICAgYm9vbGVhbiBnZXREZXNjcmlwdG9yRm9yVHlwZV8oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nLgogICAgICovCiAgICBib29sZWFuIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHVua25vd25fZmllbGRzID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHVua25vd25GaWVsZHMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Vua25vd25GaWVsZHNfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgdW5rbm93bl9maWVsZHMgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHVua25vd25GaWVsZHMuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0VW5rbm93bkZpZWxkc18oKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2FjaGVkX3NpemUgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2FjaGVkU2l6ZV8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2FjaGVkU2l6ZS4KICAgICAqLwogICAgYm9vbGVhbiBnZXRDYWNoZWRTaXplXygpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIE1lc3NhZ2Ugd2l0aCBmaWVsZCBuYW1lcyB1c2luZyB1bmRlcnNjb3JlcyB0aGF0IGNvbmZsaWN0IHdpdGggYWNjZXNzb3JzIGluCiAgICogdGhlIGJhc2UgbWVzc2FnZSBjbGFzcyBpbiBqYXZhLiBTZWUga0ZvcmJpZGRlbldvcmRMaXN0IGluCiAgICogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkKICAgICAgRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgYm9vbGVhbiBjbGFzc19fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBqYXZhLmxhbmcuT2JqZWN0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNsYXNzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNsYXNzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ2xhc3NfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBqYXZhLmxhbmcuT2JqZWN0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNsYXNzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjbGFzcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0Q2xhc3NfKCkgewogICAgICByZXR1cm4gY2xhc3NfXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOU1RBTkNFX0ZPUl9UWVBFX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGJvb2xlYW4gZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlT3JCdWlsZGVyCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEluc3RhbmNlRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlT3JCdWlsZGVyCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICByZXR1cm4gZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBUlNFUl9GT1JfVFlQRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBib29sZWFuIHBhcnNlckZvclR5cGVfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBwYXJzZXJfZm9yX3R5cGUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGFyc2VyRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1BhcnNlckZvclR5cGVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGFyc2VyRm9yVHlwZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0UGFyc2VyRm9yVHlwZV8oKSB7CiAgICAgIHJldHVybiBwYXJzZXJGb3JUeXBlX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VSSUFMSVpFRF9TSVpFX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGJvb2xlYW4gc2VyaWFsaXplZFNpemVfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzZXJpYWxpemVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1NlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2VyaWFsaXplZFNpemUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldFNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgcmV0dXJuIHNlcmlhbGl6ZWRTaXplX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxMX0ZJRUxEU19GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBib29sZWFuIGFsbEZpZWxkc19fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYWxsX2ZpZWxkcyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbGxGaWVsZHMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBbGxGaWVsZHNfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYWxsX2ZpZWxkcyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYWxsRmllbGRzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbGxGaWVsZHNfKCkgewogICAgICByZXR1cm4gYWxsRmllbGRzX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVTQ1JJUFRPUl9GT1JfVFlQRV9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBib29sZWFuIGRlc2NyaXB0b3JGb3JUeXBlX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yX2Zvcl90eXBlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlc2NyaXB0b3JGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVzY3JpcHRvckZvclR5cGVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVzY3JpcHRvcl9mb3JfdHlwZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldERlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgcmV0dXJuIGRlc2NyaXB0b3JGb3JUeXBlX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTElaQVRJT05fRVJST1JfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGJvb2xlYW4gaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGluaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSB7CiAgICAgIHJldHVybiBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9GSUVMRFNfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgYm9vbGVhbiB1bmtub3duRmllbGRzX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCB1bmtub3duX2ZpZWxkcyA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB1bmtub3duRmllbGRzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVW5rbm93bkZpZWxkc18oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCB1bmtub3duX2ZpZWxkcyA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdW5rbm93bkZpZWxkcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0VW5rbm93bkZpZWxkc18oKSB7CiAgICAgIHJldHVybiB1bmtub3duRmllbGRzX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FDSEVEX1NJWkVfRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgYm9vbGVhbiBjYWNoZWRTaXplX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjYWNoZWRTaXplIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ2FjaGVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2FjaGVkU2l6ZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0Q2FjaGVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiBjYWNoZWRTaXplX187CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEsIGNsYXNzX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMiwgZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDMsIHBhcnNlckZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg0LCBzZXJpYWxpemVkU2l6ZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDUsIGFsbEZpZWxkc19fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDYsIGRlc2NyaXB0b3JGb3JUeXBlX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woNywgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDgsIHVua25vd25GaWVsZHNfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg5LCBjYWNoZWRTaXplX18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMSwgY2xhc3NfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDIsIGRlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDMsIHBhcnNlckZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDQsIHNlcmlhbGl6ZWRTaXplX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg1LCBhbGxGaWVsZHNfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDYsIGRlc2NyaXB0b3JGb3JUeXBlX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg3LCBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg4LCB1bmtub3duRmllbGRzX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg5LCBjYWNoZWRTaXplX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc0NsYXNzXygpICE9IG90aGVyLmhhc0NsYXNzXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDbGFzc18oKSkgewogICAgICAgIGlmIChnZXRDbGFzc18oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRDbGFzc18oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpICE9IG90aGVyLmhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpIHsKICAgICAgICBpZiAoZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKQogICAgICAgICAgICAhPSBvdGhlci5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1BhcnNlckZvclR5cGVfKCkgIT0gb3RoZXIuaGFzUGFyc2VyRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUGFyc2VyRm9yVHlwZV8oKSkgewogICAgICAgIGlmIChnZXRQYXJzZXJGb3JUeXBlXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFBhcnNlckZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU2VyaWFsaXplZFNpemVfKCkgIT0gb3RoZXIuaGFzU2VyaWFsaXplZFNpemVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1NlcmlhbGl6ZWRTaXplXygpKSB7CiAgICAgICAgaWYgKGdldFNlcmlhbGl6ZWRTaXplXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFNlcmlhbGl6ZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0FsbEZpZWxkc18oKSAhPSBvdGhlci5oYXNBbGxGaWVsZHNfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0FsbEZpZWxkc18oKSkgewogICAgICAgIGlmIChnZXRBbGxGaWVsZHNfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QWxsRmllbGRzXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpICE9IG90aGVyLmhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSkgewogICAgICAgIGlmIChnZXREZXNjcmlwdG9yRm9yVHlwZV8oKQogICAgICAgICAgICAhPSBvdGhlci5nZXREZXNjcmlwdG9yRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpICE9IG90aGVyLmhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpIHsKICAgICAgICBpZiAoZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1Vua25vd25GaWVsZHNfKCkgIT0gb3RoZXIuaGFzVW5rbm93bkZpZWxkc18oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzVW5rbm93bkZpZWxkc18oKSkgewogICAgICAgIGlmIChnZXRVbmtub3duRmllbGRzXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFVua25vd25GaWVsZHNfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ2FjaGVkU2l6ZV8oKSAhPSBvdGhlci5oYXNDYWNoZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgaWYgKGdldENhY2hlZFNpemVfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Q2FjaGVkU2l6ZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0NsYXNzXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0xBU1NfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldENsYXNzXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfSU5TVEFOQ0VfRk9SX1RZUEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNQYXJzZXJGb3JUeXBlXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFSU0VSX0ZPUl9UWVBFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXRQYXJzZXJGb3JUeXBlXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzU2VyaWFsaXplZFNpemVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTRVJJQUxJWkVEX1NJWkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldFNlcmlhbGl6ZWRTaXplXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzQWxsRmllbGRzXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQUxMX0ZJRUxEU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0QWxsRmllbGRzXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVzY3JpcHRvckZvclR5cGVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERVNDUklQVE9SX0ZPUl9UWVBFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZV8oKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTklUSUFMSVpBVElPTl9FUlJPUl9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNVbmtub3duRmllbGRzXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9GSUVMRFNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldFVua25vd25GaWVsZHNfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0FDSEVEX1NJWkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldENhY2hlZFNpemVfKCkpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTWVzc2FnZSB3aXRoIGZpZWxkIG5hbWVzIHVzaW5nIHVuZGVyc2NvcmVzIHRoYXQgY29uZmxpY3Qgd2l0aCBhY2Nlc3NvcnMgaW4KICAgICAqIHRoZSBiYXNlIG1lc3NhZ2UgY2xhc3MgaW4gamF2YS4gU2VlIGtGb3JiaWRkZW5Xb3JkTGlzdCBpbgogICAgICogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY2xhc3NfXyA9IGZhbHNlOwogICAgICAgIGRlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIHBhcnNlckZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSBmYWxzZTsKICAgICAgICBhbGxGaWVsZHNfXyA9IGZhbHNlOwogICAgICAgIGRlc2NyaXB0b3JGb3JUeXBlX18gPSBmYWxzZTsKICAgICAgICBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18gPSBmYWxzZTsKICAgICAgICB1bmtub3duRmllbGRzX18gPSBmYWxzZTsKICAgICAgICBjYWNoZWRTaXplX18gPSBmYWxzZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXyA9IGNsYXNzX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBhcnNlckZvclR5cGVfXyA9IHBhcnNlckZvclR5cGVfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zZXJpYWxpemVkU2l6ZV9fID0gc2VyaWFsaXplZFNpemVfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hbGxGaWVsZHNfXyA9IGFsbEZpZWxkc19fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlc2NyaXB0b3JGb3JUeXBlX18gPSBkZXNjcmlwdG9yRm9yVHlwZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duRmllbGRzX18gPSB1bmtub3duRmllbGRzX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2FjaGVkU2l6ZV9fID0gY2FjaGVkU2l6ZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0NsYXNzXygpKSB7CiAgICAgICAgICBzZXRDbGFzc18ob3RoZXIuZ2V0Q2xhc3NfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSkgewogICAgICAgICAgc2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8ob3RoZXIuZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQYXJzZXJGb3JUeXBlXygpKSB7CiAgICAgICAgICBzZXRQYXJzZXJGb3JUeXBlXyhvdGhlci5nZXRQYXJzZXJGb3JUeXBlXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1NlcmlhbGl6ZWRTaXplXygpKSB7CiAgICAgICAgICBzZXRTZXJpYWxpemVkU2l6ZV8ob3RoZXIuZ2V0U2VyaWFsaXplZFNpemVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQWxsRmllbGRzXygpKSB7CiAgICAgICAgICBzZXRBbGxGaWVsZHNfKG90aGVyLmdldEFsbEZpZWxkc18oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSkgewogICAgICAgICAgc2V0RGVzY3JpcHRvckZvclR5cGVfKG90aGVyLmdldERlc2NyaXB0b3JGb3JUeXBlXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpIHsKICAgICAgICAgIHNldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKG90aGVyLmdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzVW5rbm93bkZpZWxkc18oKSkgewogICAgICAgICAgc2V0VW5rbm93bkZpZWxkc18ob3RoZXIuZ2V0VW5rbm93bkZpZWxkc18oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgICBzZXRDYWNoZWRTaXplXyhvdGhlci5nZXRDYWNoZWRTaXplXygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBjbGFzc19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIHBhcnNlckZvclR5cGVfXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBzZXJpYWxpemVkU2l6ZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIGFsbEZpZWxkc19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDg6IHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JGb3JUeXBlX18gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA1NjogewogICAgICAgICAgICAgICAgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgNjQ6IHsKICAgICAgICAgICAgICAgIHVua25vd25GaWVsZHNfXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQKICAgICAgICAgICAgICBjYXNlIDcyOiB7CiAgICAgICAgICAgICAgICBjYWNoZWRTaXplX18gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgYm9vbGVhbiBjbGFzc19fIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2xhc3MgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjbGFzcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NsYXNzXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2xhc3MgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY2xhc3MuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldENsYXNzXygpIHsKICAgICAgICByZXR1cm4gY2xhc3NfXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNsYXNzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2xhc3NfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgY2xhc3NfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgY2xhc3NfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9pbnN0YW5jZV9mb3JfdHlwZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9pbnN0YW5jZV9mb3JfdHlwZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlT3JCdWlsZGVyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9pbnN0YW5jZV9mb3JfdHlwZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIHBhcnNlckZvclR5cGVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBhcnNlckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXJzZXJGb3JUeXBlXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcGFyc2VyX2Zvcl90eXBlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHBhcnNlckZvclR5cGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFBhcnNlckZvclR5cGVfKCkgewogICAgICAgIHJldHVybiBwYXJzZXJGb3JUeXBlX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcGFyc2VyX2Zvcl90eXBlID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFyc2VyRm9yVHlwZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhcnNlckZvclR5cGVfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgcGFyc2VyRm9yVHlwZV9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhcnNlckZvclR5cGVfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBwYXJzZXJGb3JUeXBlX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIHNlcmlhbGl6ZWRTaXplX18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBzZXJpYWxpemVkX3NpemUgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzZXJpYWxpemVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZF9zaXplID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHNlcmlhbGl6ZWRTaXplLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWRTaXplX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZF9zaXplID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc2VyaWFsaXplZFNpemUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTZXJpYWxpemVkU2l6ZV8oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBzZXJpYWxpemVkU2l6ZV9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gYWxsRmllbGRzX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGFsbF9maWVsZHMgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbGxGaWVsZHMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBbGxGaWVsZHNfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGFsbF9maWVsZHMgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYWxsRmllbGRzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbGxGaWVsZHNfKCkgewogICAgICAgIHJldHVybiBhbGxGaWVsZHNfXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGFsbF9maWVsZHMgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhbGxGaWVsZHMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBbGxGaWVsZHNfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgYWxsRmllbGRzX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBhbGxfZmllbGRzID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQWxsRmllbGRzXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgYWxsRmllbGRzX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGRlc2NyaXB0b3JGb3JUeXBlX18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yX2Zvcl90eXBlID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVzY3JpcHRvckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlc2NyaXB0b3JfZm9yX3R5cGUgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldERlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgICByZXR1cm4gZGVzY3JpcHRvckZvclR5cGVfXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yX2Zvcl90eXBlID0gNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVzY3JpcHRvckZvclR5cGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZXNjcmlwdG9yRm9yVHlwZV8oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBkZXNjcmlwdG9yRm9yVHlwZV9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlc2NyaXB0b3JfZm9yX3R5cGUgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGRlc2NyaXB0b3JGb3JUeXBlX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGluaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkgewogICAgICAgIHJldHVybiBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGluaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIHVua25vd25GaWVsZHNfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHVua25vd25fZmllbGRzID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdW5rbm93bkZpZWxkcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Vua25vd25GaWVsZHNfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCB1bmtub3duX2ZpZWxkcyA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB1bmtub3duRmllbGRzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRVbmtub3duRmllbGRzXygpIHsKICAgICAgICByZXR1cm4gdW5rbm93bkZpZWxkc19fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHVua25vd25fZmllbGRzID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5rbm93bkZpZWxkcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFVua25vd25GaWVsZHNfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgdW5rbm93bkZpZWxkc19fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHVua25vd25fZmllbGRzID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bkZpZWxkc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIHVua25vd25GaWVsZHNfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gY2FjaGVkU2l6ZV9fIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNhY2hlZFNpemUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDYWNoZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjYWNoZWRTaXplLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRDYWNoZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gY2FjaGVkU2l6ZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2FjaGVkX3NpemUgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBjYWNoZWRTaXplIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2FjaGVkU2l6ZV8oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBjYWNoZWRTaXplX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNhY2hlZFNpemVfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBjYWNoZWRTaXplX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2xhc3MgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2xhc3MgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NsYXNzXygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2xhc3MgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNsYXNzLgogICAgICovCiAgICBib29sZWFuIGdldENsYXNzXygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2RlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEluc3RhbmNlRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2RlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9wYXJzZXJfZm9yX3R5cGUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGFyc2VyRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUGFyc2VyRm9yVHlwZV8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3BhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGFyc2VyRm9yVHlwZS4KICAgICAqLwogICAgYm9vbGVhbiBnZXRQYXJzZXJGb3JUeXBlXygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfc2VyaWFsaXplZF9zaXplID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNlcmlhbGl6ZWRTaXplIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTZXJpYWxpemVkU2l6ZV8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfc2VyaWFsaXplZF9zaXplID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkU2l6ZS4KICAgICAqLwogICAgYm9vbGVhbiBnZXRTZXJpYWxpemVkU2l6ZV8oKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2FsbF9maWVsZHMgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYWxsRmllbGRzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBbGxGaWVsZHNfKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2FsbF9maWVsZHMgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGFsbEZpZWxkcy4KICAgICAqLwogICAgYm9vbGVhbiBnZXRBbGxGaWVsZHNfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9kZXNjcmlwdG9yX2Zvcl90eXBlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlc2NyaXB0b3JGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfZGVzY3JpcHRvcl9mb3JfdHlwZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RGVzY3JpcHRvckZvclR5cGVfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9pbml0aWFsaXphdGlvbl9lcnJvcl9zdHJpbmcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nLgogICAgICovCiAgICBib29sZWFuIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgKiBvcHRpb25hbCBib29sIF91bmtub3duX2ZpZWxkcyA9IDg7CiAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NhY2hlZF9zaXplID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNhY2hlZFNpemUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NhY2hlZFNpemVfKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAqIG9wdGlvbmFsIGJvb2wgX3Vua25vd25fZmllbGRzID0gODsKICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2FjaGVkX3NpemUgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNhY2hlZFNpemUuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0Q2FjaGVkU2l6ZV8oKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBNZXNzYWdlIHdpdGggZmllbGQgbmFtZXMgdXNpbmcgbGVhZGluZyB1bmRlcnNjb3JlcyB0aGF0IGNvbmZsaWN0IHdpdGgKICAgKiBhY2Nlc3NvcnMgaW4gdGhlIGJhc2UgbWVzc2FnZSBjbGFzcyBpbiBqYXZhLiBTZWUga0ZvcmJpZGRlbldvcmRMaXN0IGluCiAgICogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSkKICAgICAgRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX0NMQVNTX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGJvb2xlYW4gQ2xhc3NfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2xhc3MgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2xhc3MgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDbGFzc18oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NsYXNzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjbGFzcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0Q2xhc3NfKCkgewogICAgICByZXR1cm4gQ2xhc3NfXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfREVGQVVMVF9JTlNUQU5DRV9GT1JfVFlQRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBib29sZWFuIERlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfZGVmYXVsdF9pbnN0YW5jZV9mb3JfdHlwZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2RlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICByZXR1cm4gRGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9QQVJTRVJfRk9SX1RZUEVfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgYm9vbGVhbiBQYXJzZXJGb3JUeXBlX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3BhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXJzZXJGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUGFyc2VyRm9yVHlwZV8oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3BhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGFyc2VyRm9yVHlwZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0UGFyc2VyRm9yVHlwZV8oKSB7CiAgICAgIHJldHVybiBQYXJzZXJGb3JUeXBlX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX1NFUklBTElaRURfU0laRV9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBib29sZWFuIFNlcmlhbGl6ZWRTaXplX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfc2VyaWFsaXplZF9zaXplID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNlcmlhbGl6ZWRTaXplIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU2VyaWFsaXplZFNpemVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3NlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2VyaWFsaXplZFNpemUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldFNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgcmV0dXJuIFNlcmlhbGl6ZWRTaXplX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX0FMTF9GSUVMRFNfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgYm9vbGVhbiBBbGxGaWVsZHNfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9hbGxfZmllbGRzID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGFsbEZpZWxkcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0FsbEZpZWxkc18oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfYWxsX2ZpZWxkcyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYWxsRmllbGRzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbGxGaWVsZHNfKCkgewogICAgICByZXR1cm4gQWxsRmllbGRzX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX0RFU0NSSVBUT1JfRk9SX1RZUEVfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgYm9vbGVhbiBEZXNjcmlwdG9yRm9yVHlwZV9fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2Rlc2NyaXB0b3JfZm9yX3R5cGUgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVzY3JpcHRvckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfZGVzY3JpcHRvcl9mb3JfdHlwZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldERlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgcmV0dXJuIERlc2NyaXB0b3JGb3JUeXBlX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX0lOSVRJQUxJWkFUSU9OX0VSUk9SX1NUUklOR19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBib29sZWFuIEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9pbml0aWFsaXphdGlvbl9lcnJvcl9zdHJpbmcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2luaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSB7CiAgICAgIHJldHVybiBJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX0NBQ0hFRF9TSVpFX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIGJvb2xlYW4gQ2FjaGVkU2l6ZV9fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAqIG9wdGlvbmFsIGJvb2wgX3Vua25vd25fZmllbGRzID0gODsKICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2FjaGVkX3NpemUgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NhY2hlZFNpemVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAqIG9wdGlvbmFsIGJvb2wgX3Vua25vd25fZmllbGRzID0gODsKICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2FjaGVkX3NpemUgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNhY2hlZFNpemUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldENhY2hlZFNpemVfKCkgewogICAgICByZXR1cm4gQ2FjaGVkU2l6ZV9fOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxLCBDbGFzc19fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDIsIERlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgzLCBQYXJzZXJGb3JUeXBlX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woNCwgU2VyaWFsaXplZFNpemVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg1LCBBbGxGaWVsZHNfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg2LCBEZXNjcmlwdG9yRm9yVHlwZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDcsIEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg5LCBDYWNoZWRTaXplX18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMSwgQ2xhc3NfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDIsIERlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDMsIFBhcnNlckZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDQsIFNlcmlhbGl6ZWRTaXplX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg1LCBBbGxGaWVsZHNfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDYsIERlc2NyaXB0b3JGb3JUeXBlX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg3LCBJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg5LCBDYWNoZWRTaXplX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc0NsYXNzXygpICE9IG90aGVyLmhhc0NsYXNzXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDbGFzc18oKSkgewogICAgICAgIGlmIChnZXRDbGFzc18oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRDbGFzc18oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpICE9IG90aGVyLmhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpIHsKICAgICAgICBpZiAoZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKQogICAgICAgICAgICAhPSBvdGhlci5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1BhcnNlckZvclR5cGVfKCkgIT0gb3RoZXIuaGFzUGFyc2VyRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUGFyc2VyRm9yVHlwZV8oKSkgewogICAgICAgIGlmIChnZXRQYXJzZXJGb3JUeXBlXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFBhcnNlckZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU2VyaWFsaXplZFNpemVfKCkgIT0gb3RoZXIuaGFzU2VyaWFsaXplZFNpemVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1NlcmlhbGl6ZWRTaXplXygpKSB7CiAgICAgICAgaWYgKGdldFNlcmlhbGl6ZWRTaXplXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFNlcmlhbGl6ZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0FsbEZpZWxkc18oKSAhPSBvdGhlci5oYXNBbGxGaWVsZHNfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0FsbEZpZWxkc18oKSkgewogICAgICAgIGlmIChnZXRBbGxGaWVsZHNfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QWxsRmllbGRzXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpICE9IG90aGVyLmhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSkgewogICAgICAgIGlmIChnZXREZXNjcmlwdG9yRm9yVHlwZV8oKQogICAgICAgICAgICAhPSBvdGhlci5nZXREZXNjcmlwdG9yRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpICE9IG90aGVyLmhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpIHsKICAgICAgICBpZiAoZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0NhY2hlZFNpemVfKCkgIT0gb3RoZXIuaGFzQ2FjaGVkU2l6ZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ2FjaGVkU2l6ZV8oKSkgewogICAgICAgIGlmIChnZXRDYWNoZWRTaXplXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldENhY2hlZFNpemVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNDbGFzc18oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIF9DTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0Q2xhc3NfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgX0RFRkFVTFRfSU5TVEFOQ0VfRk9SX1RZUEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNQYXJzZXJGb3JUeXBlXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgX1BBUlNFUl9GT1JfVFlQRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0UGFyc2VyRm9yVHlwZV8oKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1NlcmlhbGl6ZWRTaXplXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgX1NFUklBTElaRURfU0laRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0U2VyaWFsaXplZFNpemVfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNBbGxGaWVsZHNfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBfQUxMX0ZJRUxEU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0QWxsRmllbGRzXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVzY3JpcHRvckZvclR5cGVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBfREVTQ1JJUFRPUl9GT1JfVFlQRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGVfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgX0lOSVRJQUxJWkFUSU9OX0VSUk9SX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NhY2hlZFNpemVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBfQ0FDSEVEX1NJWkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldENhY2hlZFNpemVfKCkpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1lc3NhZ2Ugd2l0aCBmaWVsZCBuYW1lcyB1c2luZyBsZWFkaW5nIHVuZGVyc2NvcmVzIHRoYXQgY29uZmxpY3Qgd2l0aAogICAgICogYWNjZXNzb3JzIGluIHRoZSBiYXNlIG1lc3NhZ2UgY2xhc3MgaW4gamF2YS4gU2VlIGtGb3JiaWRkZW5Xb3JkTGlzdCBpbgogICAgICogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBDbGFzc19fID0gZmFsc2U7CiAgICAgICAgRGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gZmFsc2U7CiAgICAgICAgUGFyc2VyRm9yVHlwZV9fID0gZmFsc2U7CiAgICAgICAgU2VyaWFsaXplZFNpemVfXyA9IGZhbHNlOwogICAgICAgIEFsbEZpZWxkc19fID0gZmFsc2U7CiAgICAgICAgRGVzY3JpcHRvckZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGZhbHNlOwogICAgICAgIENhY2hlZFNpemVfXyA9IGZhbHNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5DbGFzc19fID0gQ2xhc3NfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5EZWZhdWx0SW5zdGFuY2VGb3JUeXBlX18gPSBEZWZhdWx0SW5zdGFuY2VGb3JUeXBlX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuUGFyc2VyRm9yVHlwZV9fID0gUGFyc2VyRm9yVHlwZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LlNlcmlhbGl6ZWRTaXplX18gPSBTZXJpYWxpemVkU2l6ZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LkFsbEZpZWxkc19fID0gQWxsRmllbGRzX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuRGVzY3JpcHRvckZvclR5cGVfXyA9IERlc2NyaXB0b3JGb3JUeXBlX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fID0gSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LkNhY2hlZFNpemVfXyA9IENhY2hlZFNpemVfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQ2xhc3NfKCkpIHsKICAgICAgICAgIHNldENsYXNzXyhvdGhlci5nZXRDbGFzc18oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKSB7CiAgICAgICAgICBzZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXyhvdGhlci5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1BhcnNlckZvclR5cGVfKCkpIHsKICAgICAgICAgIHNldFBhcnNlckZvclR5cGVfKG90aGVyLmdldFBhcnNlckZvclR5cGVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU2VyaWFsaXplZFNpemVfKCkpIHsKICAgICAgICAgIHNldFNlcmlhbGl6ZWRTaXplXyhvdGhlci5nZXRTZXJpYWxpemVkU2l6ZV8oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNBbGxGaWVsZHNfKCkpIHsKICAgICAgICAgIHNldEFsbEZpZWxkc18ob3RoZXIuZ2V0QWxsRmllbGRzXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpKSB7CiAgICAgICAgICBzZXREZXNjcmlwdG9yRm9yVHlwZV8ob3RoZXIuZ2V0RGVzY3JpcHRvckZvclR5cGVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSkgewogICAgICAgICAgc2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18ob3RoZXIuZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgICBzZXRDYWNoZWRTaXplXyhvdGhlci5nZXRDYWNoZWRTaXplXygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBDbGFzc19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgRGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIFBhcnNlckZvclR5cGVfXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBTZXJpYWxpemVkU2l6ZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIEFsbEZpZWxkc19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDg6IHsKICAgICAgICAgICAgICAgIERlc2NyaXB0b3JGb3JUeXBlX18gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA1NjogewogICAgICAgICAgICAgICAgSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgNzI6IHsKICAgICAgICAgICAgICAgIENhY2hlZFNpemVfXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBib29sZWFuIENsYXNzX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfY2xhc3MgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjbGFzcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NsYXNzXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NsYXNzID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNsYXNzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRDbGFzc18oKSB7CiAgICAgICAgcmV0dXJuIENsYXNzX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NsYXNzID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY2xhc3MgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDbGFzc18oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBDbGFzc19fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBqYXZhLmxhbmcuT2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9jbGFzcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgQ2xhc3NfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gRGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2RlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlT3JCdWlsZGVyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9kZWZhdWx0X2luc3RhbmNlX2Zvcl90eXBlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICAgIHJldHVybiBEZWZhdWx0SW5zdGFuY2VGb3JUeXBlX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2RlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBEZWZhdWx0SW5zdGFuY2VGb3JUeXBlX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2RlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgRGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBQYXJzZXJGb3JUeXBlX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfcGFyc2VyX2Zvcl90eXBlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGFyc2VyRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BhcnNlckZvclR5cGVfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfcGFyc2VyX2Zvcl90eXBlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHBhcnNlckZvclR5cGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFBhcnNlckZvclR5cGVfKCkgewogICAgICAgIHJldHVybiBQYXJzZXJGb3JUeXBlX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3BhcnNlcl9mb3JfdHlwZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhcnNlckZvclR5cGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXJzZXJGb3JUeXBlXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIFBhcnNlckZvclR5cGVfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfcGFyc2VyX2Zvcl90eXBlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFyc2VyRm9yVHlwZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIFBhcnNlckZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gU2VyaWFsaXplZFNpemVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9zZXJpYWxpemVkX3NpemUgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzZXJpYWxpemVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3NlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkU2l6ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0U2VyaWFsaXplZFNpemVfKCkgewogICAgICAgIHJldHVybiBTZXJpYWxpemVkU2l6ZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9zZXJpYWxpemVkX3NpemUgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzZXJpYWxpemVkU2l6ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNlcmlhbGl6ZWRTaXplXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIFNlcmlhbGl6ZWRTaXplX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX3NlcmlhbGl6ZWRfc2l6ZSA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgU2VyaWFsaXplZFNpemVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gQWxsRmllbGRzX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9hbGxfZmllbGRzID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYWxsRmllbGRzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQWxsRmllbGRzXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfYWxsX2ZpZWxkcyA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhbGxGaWVsZHMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEFsbEZpZWxkc18oKSB7CiAgICAgICAgcmV0dXJuIEFsbEZpZWxkc19fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2FsbF9maWVsZHMgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhbGxGaWVsZHMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBbGxGaWVsZHNfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgQWxsRmllbGRzX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfYWxsX2ZpZWxkcyA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckFsbEZpZWxkc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIEFsbEZpZWxkc19fID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBEZXNjcmlwdG9yRm9yVHlwZV9fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2Rlc2NyaXB0b3JfZm9yX3R5cGUgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXNjcmlwdG9yRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2Rlc2NyaXB0b3JfZm9yX3R5cGUgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldERlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgICByZXR1cm4gRGVzY3JpcHRvckZvclR5cGVfXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfZGVzY3JpcHRvcl9mb3JfdHlwZSA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlc2NyaXB0b3JGb3JUeXBlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVzY3JpcHRvckZvclR5cGVfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgRGVzY3JpcHRvckZvclR5cGVfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBfZGVzY3JpcHRvcl9mb3JfdHlwZSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgRGVzY3JpcHRvckZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2luaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2luaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpIHsKICAgICAgICByZXR1cm4gSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ19fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9pbml0aWFsaXphdGlvbl9lcnJvcl9zdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2luaXRpYWxpemF0aW9uX2Vycm9yX3N0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIENhY2hlZFNpemVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAgICogb3B0aW9uYWwgYm9vbCBfdW5rbm93bl9maWVsZHMgPSA4OwogICAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NhY2hlZF9zaXplID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NhY2hlZFNpemVfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgICAqIG9wdGlvbmFsIGJvb2wgX3Vua25vd25fZmllbGRzID0gODsKICAgICAgICogb2Jzb2xldGUuIGtlcHQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IG9mIGdlbmVyYXRlZCBjb2RlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIF9jYWNoZWRfc2l6ZSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjYWNoZWRTaXplLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRDYWNoZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gQ2FjaGVkU2l6ZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAgICogb3B0aW9uYWwgYm9vbCBfdW5rbm93bl9maWVsZHMgPSA4OwogICAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NhY2hlZF9zaXplID0gOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY2FjaGVkU2l6ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENhY2hlZFNpemVfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgQ2FjaGVkU2l6ZV9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAgICogb3B0aW9uYWwgYm9vbCBfdW5rbm93bl9maWVsZHMgPSA4OwogICAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgX2NhY2hlZF9zaXplID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2FjaGVkU2l6ZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIENhY2hlZFNpemVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yYmlkZGVuV29yZHNMZWFkaW5nVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0xlYWRpbmdVbmRlcnNjb3JlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGphdmEubGFuZy5PYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2xhc3MgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2xhc3MgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NsYXNzXygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2xhc3MuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0Q2xhc3NfKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlT3JCdWlsZGVyCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRTaXplID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNlcmlhbGl6ZWRTaXplIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTZXJpYWxpemVkU2l6ZV8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZFNpemUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNlcmlhbGl6ZWRTaXplLgogICAgICovCiAgICBib29sZWFuIGdldFNlcmlhbGl6ZWRTaXplXygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBwYXJzZXJGb3JUeXBlID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBhcnNlckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1BhcnNlckZvclR5cGVfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcGFyc2VyRm9yVHlwZSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGFyc2VyRm9yVHlwZS4KICAgICAqLwogICAgYm9vbGVhbiBnZXRQYXJzZXJGb3JUeXBlXygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcjoKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyOgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nLgogICAgICovCiAgICBib29sZWFuIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlc2NyaXB0b3JGb3JUeXBlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlc2NyaXB0b3JGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yRm9yVHlwZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RGVzY3JpcHRvckZvclR5cGVfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGFsbEZpZWxkcyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbGxGaWVsZHMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0FsbEZpZWxkc18oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBhbGxGaWVsZHMgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGFsbEZpZWxkcy4KICAgICAqLwogICAgYm9vbGVhbiBnZXRBbGxGaWVsZHNfKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgKiBvcHRpb25hbCBib29sIHVua25vd25GaWVsZHMgPSA4OwogICAgICogb2Jzb2xldGUuIGtlcHQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IG9mIGdlbmVyYXRlZCBjb2RlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNhY2hlZFNpemUgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2FjaGVkU2l6ZV8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRPRE86IHJlLWVuYWJsZQogICAgICogb3B0aW9uYWwgYm9vbCB1bmtub3duRmllbGRzID0gODsKICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRTaXplID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjYWNoZWRTaXplLgogICAgICovCiAgICBib29sZWFuIGdldENhY2hlZFNpemVfKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogTWVzc2FnZSB3aXRoIGZpZWxkIG5hbWVzIGluIGNhbWVsIGNhc2UgdGhhdCBjb25mbGljdCB3aXRoIGFjY2Vzc29ycyBpbiB0aGUKICAgKiBiYXNlIG1lc3NhZ2UgY2xhc3MgaW4gamF2YS4gU2VlIGtGb3JiaWRkZW5Xb3JkTGlzdCBpbgogICAqIHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuY2MKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UpCiAgICAgIEZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGJvb2xlYW4gY2xhc3NfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjbGFzcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NsYXNzXygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2xhc3MuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldENsYXNzXygpIHsKICAgICAgcmV0dXJuIGNsYXNzX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVElOU1RBTkNFRk9SVFlQRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRJbnN0YW5jZUZvclR5cGVfXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVJJQUxJWkVEU0laRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBib29sZWFuIHNlcmlhbGl6ZWRTaXplX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZFNpemUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc2VyaWFsaXplZFNpemUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZFNpemUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNlcmlhbGl6ZWRTaXplLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiBzZXJpYWxpemVkU2l6ZV9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBUlNFUkZPUlRZUEVfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgYm9vbGVhbiBwYXJzZXJGb3JUeXBlX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBwYXJzZXJGb3JUeXBlID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBhcnNlckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXJzZXJGb3JUeXBlXygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlckZvclR5cGUgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBhcnNlckZvclR5cGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldFBhcnNlckZvclR5cGVfKCkgewogICAgICByZXR1cm4gcGFyc2VyRm9yVHlwZV9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxJWkFUSU9ORVJST1JTVFJJTkdfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgYm9vbGVhbiBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcjoKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcjoKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSB7CiAgICAgIHJldHVybiBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVTQ1JJUFRPUkZPUlRZUEVfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgYm9vbGVhbiBkZXNjcmlwdG9yRm9yVHlwZV9fID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVzY3JpcHRvckZvclR5cGUgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVzY3JpcHRvckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZXNjcmlwdG9yRm9yVHlwZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvckZvclR5cGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldERlc2NyaXB0b3JGb3JUeXBlXygpIHsKICAgICAgcmV0dXJuIGRlc2NyaXB0b3JGb3JUeXBlX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxMRklFTERTX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGJvb2xlYW4gYWxsRmllbGRzX18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBhbGxGaWVsZHMgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYWxsRmllbGRzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQWxsRmllbGRzXygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGFsbEZpZWxkcyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYWxsRmllbGRzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbGxGaWVsZHNfKCkgewogICAgICByZXR1cm4gYWxsRmllbGRzX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FDSEVEU0laRV9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBib29sZWFuIGNhY2hlZFNpemVfXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgKiBvcHRpb25hbCBib29sIHVua25vd25GaWVsZHMgPSA4OwogICAgICogb2Jzb2xldGUuIGtlcHQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IG9mIGdlbmVyYXRlZCBjb2RlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNhY2hlZFNpemUgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NhY2hlZFNpemVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUT0RPOiByZS1lbmFibGUKICAgICAqIG9wdGlvbmFsIGJvb2wgdW5rbm93bkZpZWxkcyA9IDg7CiAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2FjaGVkU2l6ZSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2FjaGVkU2l6ZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0Q2FjaGVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiBjYWNoZWRTaXplX187CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEsIGNsYXNzX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMiwgZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDMsIHNlcmlhbGl6ZWRTaXplX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woNCwgcGFyc2VyRm9yVHlwZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDUsIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg2LCBkZXNjcmlwdG9yRm9yVHlwZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDcsIGFsbEZpZWxkc19fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDksIGNhY2hlZFNpemVfXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxLCBjbGFzc19fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMiwgZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMywgc2VyaWFsaXplZFNpemVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDQsIHBhcnNlckZvclR5cGVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDUsIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDYsIGRlc2NyaXB0b3JGb3JUeXBlX18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg3LCBhbGxGaWVsZHNfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDksIGNhY2hlZFNpemVfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzQ2xhc3NfKCkgIT0gb3RoZXIuaGFzQ2xhc3NfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0NsYXNzXygpKSB7CiAgICAgICAgaWYgKGdldENsYXNzXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldENsYXNzXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgIT0gb3RoZXIuaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSkgewogICAgICAgIGlmIChnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU2VyaWFsaXplZFNpemVfKCkgIT0gb3RoZXIuaGFzU2VyaWFsaXplZFNpemVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1NlcmlhbGl6ZWRTaXplXygpKSB7CiAgICAgICAgaWYgKGdldFNlcmlhbGl6ZWRTaXplXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFNlcmlhbGl6ZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1BhcnNlckZvclR5cGVfKCkgIT0gb3RoZXIuaGFzUGFyc2VyRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUGFyc2VyRm9yVHlwZV8oKSkgewogICAgICAgIGlmIChnZXRQYXJzZXJGb3JUeXBlXygpCiAgICAgICAgICAgICE9IG90aGVyLmdldFBhcnNlckZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSAhPSBvdGhlci5oYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKSB7CiAgICAgICAgaWYgKGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSAhPSBvdGhlci5oYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVzY3JpcHRvckZvclR5cGVfKCkpIHsKICAgICAgICBpZiAoZ2V0RGVzY3JpcHRvckZvclR5cGVfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVzY3JpcHRvckZvclR5cGVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQWxsRmllbGRzXygpICE9IG90aGVyLmhhc0FsbEZpZWxkc18oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQWxsRmllbGRzXygpKSB7CiAgICAgICAgaWYgKGdldEFsbEZpZWxkc18oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRBbGxGaWVsZHNfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ2FjaGVkU2l6ZV8oKSAhPSBvdGhlci5oYXNDYWNoZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgaWYgKGdldENhY2hlZFNpemVfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Q2FjaGVkU2l6ZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0NsYXNzXygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0xBU1NfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldENsYXNzXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRJTlNUQU5DRUZPUlRZUEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNTZXJpYWxpemVkU2l6ZV8oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNFUklBTElaRURTSVpFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXRTZXJpYWxpemVkU2l6ZV8oKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1BhcnNlckZvclR5cGVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQVJTRVJGT1JUWVBFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXRQYXJzZXJGb3JUeXBlXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOSVRJQUxJWkFUSU9ORVJST1JTVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFU0NSSVBUT1JGT1JUWVBFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZV8oKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0FsbEZpZWxkc18oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFMTEZJRUxEU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0QWxsRmllbGRzXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzQ2FjaGVkU2l6ZV8oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENBQ0hFRFNJWkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldENhY2hlZFNpemVfKCkpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1lc3NhZ2Ugd2l0aCBmaWVsZCBuYW1lcyBpbiBjYW1lbCBjYXNlIHRoYXQgY29uZmxpY3Qgd2l0aCBhY2Nlc3NvcnMgaW4gdGhlCiAgICAgKiBiYXNlIG1lc3NhZ2UgY2xhc3MgaW4gamF2YS4gU2VlIGtGb3JiaWRkZW5Xb3JkTGlzdCBpbgogICAgICogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5jYwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBjbGFzc19fID0gZmFsc2U7CiAgICAgICAgZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gZmFsc2U7CiAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IGZhbHNlOwogICAgICAgIHBhcnNlckZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGZhbHNlOwogICAgICAgIGRlc2NyaXB0b3JGb3JUeXBlX18gPSBmYWxzZTsKICAgICAgICBhbGxGaWVsZHNfXyA9IGZhbHNlOwogICAgICAgIGNhY2hlZFNpemVfXyA9IGZhbHNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jbGFzc19fID0gY2xhc3NfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0SW5zdGFuY2VGb3JUeXBlX18gPSBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc2VyaWFsaXplZFNpemVfXyA9IHNlcmlhbGl6ZWRTaXplX187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGFyc2VyRm9yVHlwZV9fID0gcGFyc2VyRm9yVHlwZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZXNjcmlwdG9yRm9yVHlwZV9fID0gZGVzY3JpcHRvckZvclR5cGVfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hbGxGaWVsZHNfXyA9IGFsbEZpZWxkc19fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNhY2hlZFNpemVfXyA9IGNhY2hlZFNpemVfXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQ2xhc3NfKCkpIHsKICAgICAgICAgIHNldENsYXNzXyhvdGhlci5nZXRDbGFzc18oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKSB7CiAgICAgICAgICBzZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXyhvdGhlci5nZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1NlcmlhbGl6ZWRTaXplXygpKSB7CiAgICAgICAgICBzZXRTZXJpYWxpemVkU2l6ZV8ob3RoZXIuZ2V0U2VyaWFsaXplZFNpemVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUGFyc2VyRm9yVHlwZV8oKSkgewogICAgICAgICAgc2V0UGFyc2VyRm9yVHlwZV8ob3RoZXIuZ2V0UGFyc2VyRm9yVHlwZV8oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKSB7CiAgICAgICAgICBzZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXyhvdGhlci5nZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0Rlc2NyaXB0b3JGb3JUeXBlXygpKSB7CiAgICAgICAgICBzZXREZXNjcmlwdG9yRm9yVHlwZV8ob3RoZXIuZ2V0RGVzY3JpcHRvckZvclR5cGVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQWxsRmllbGRzXygpKSB7CiAgICAgICAgICBzZXRBbGxGaWVsZHNfKG90aGVyLmdldEFsbEZpZWxkc18oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgICBzZXRDYWNoZWRTaXplXyhvdGhlci5nZXRDYWNoZWRTaXplXygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBjbGFzc19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgZGVmYXVsdEluc3RhbmNlRm9yVHlwZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgcGFyc2VyRm9yVHlwZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdG9yRm9yVHlwZV9fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGNhc2UgNTY6IHsKICAgICAgICAgICAgICAgIGFsbEZpZWxkc19fID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgNzI6IHsKICAgICAgICAgICAgICAgIGNhY2hlZFNpemVfXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBib29sZWFuIGNsYXNzX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNsYXNzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ2xhc3NfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogamF2YS5sYW5nLk9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjbGFzcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjbGFzcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0Q2xhc3NfKCkgewogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBqYXZhLmxhbmcuT2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNsYXNzID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY2xhc3MgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDbGFzc18oYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBjbGFzc19fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBqYXZhLmxhbmcuT2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGNsYXNzID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2xhc3NfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBjbGFzc19fID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEluc3RhbmNlRm9yVHlwZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGVfKCkgewogICAgICAgIHJldHVybiBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGVPckJ1aWxkZXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdEluc3RhbmNlRm9yVHlwZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRJbnN0YW5jZUZvclR5cGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGRlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZU9yQnVpbGRlcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0SW5zdGFuY2VGb3JUeXBlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGRlZmF1bHRJbnN0YW5jZUZvclR5cGVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gc2VyaWFsaXplZFNpemVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRTaXplID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc2VyaWFsaXplZFNpemUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHNlcmlhbGl6ZWRTaXplID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHNlcmlhbGl6ZWRTaXplLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZWRTaXplX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZFNpemUgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzZXJpYWxpemVkU2l6ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNlcmlhbGl6ZWRTaXplXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgc2VyaWFsaXplZFNpemUgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIHBhcnNlckZvclR5cGVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlckZvclR5cGUgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXJzZXJGb3JUeXBlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUGFyc2VyRm9yVHlwZV8oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlckZvclR5cGUgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGFyc2VyRm9yVHlwZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UGFyc2VyRm9yVHlwZV8oKSB7CiAgICAgICAgcmV0dXJuIHBhcnNlckZvclR5cGVfXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBwYXJzZXJGb3JUeXBlID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFyc2VyRm9yVHlwZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhcnNlckZvclR5cGVfKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgcGFyc2VyRm9yVHlwZV9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHBhcnNlckZvclR5cGUgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYXJzZXJGb3JUeXBlXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgcGFyc2VyRm9yVHlwZV9fID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyOgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0luaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyOgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfKCkgewogICAgICAgIHJldHVybiBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlcjoKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZyA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyOgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBpbml0aWFsaXphdGlvbkVycm9yU3RyaW5nID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gZGVzY3JpcHRvckZvclR5cGVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlc2NyaXB0b3JGb3JUeXBlID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVzY3JpcHRvckZvclR5cGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlc2NyaXB0b3JGb3JUeXBlID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlc2NyaXB0b3JGb3JUeXBlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXREZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3JGb3JUeXBlX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVzY3JpcHRvckZvclR5cGUgPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZXNjcmlwdG9yRm9yVHlwZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlc2NyaXB0b3JGb3JUeXBlXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGRlc2NyaXB0b3JGb3JUeXBlX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVzY3JpcHRvckZvclR5cGUgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZXNjcmlwdG9yRm9yVHlwZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGRlc2NyaXB0b3JGb3JUeXBlX18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGFsbEZpZWxkc19fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYWxsRmllbGRzID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYWxsRmllbGRzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQWxsRmllbGRzXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYWxsRmllbGRzID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGFsbEZpZWxkcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0QWxsRmllbGRzXygpIHsKICAgICAgICByZXR1cm4gYWxsRmllbGRzX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYWxsRmllbGRzID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYWxsRmllbGRzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QWxsRmllbGRzXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGFsbEZpZWxkc19fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGFsbEZpZWxkcyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckFsbEZpZWxkc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGFsbEZpZWxkc19fID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBjYWNoZWRTaXplX18gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgICAqIG9wdGlvbmFsIGJvb2wgdW5rbm93bkZpZWxkcyA9IDg7CiAgICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRTaXplID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NhY2hlZFNpemVfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgICAqIG9wdGlvbmFsIGJvb2wgdW5rbm93bkZpZWxkcyA9IDg7CiAgICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRTaXplID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNhY2hlZFNpemUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldENhY2hlZFNpemVfKCkgewogICAgICAgIHJldHVybiBjYWNoZWRTaXplX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRPRE86IHJlLWVuYWJsZQogICAgICAgKiBvcHRpb25hbCBib29sIHVua25vd25GaWVsZHMgPSA4OwogICAgICAgKiBvYnNvbGV0ZS4ga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb2YgZ2VuZXJhdGVkIGNvZGUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgY2FjaGVkU2l6ZSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNhY2hlZFNpemUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDYWNoZWRTaXplXyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGNhY2hlZFNpemVfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVE9ETzogcmUtZW5hYmxlCiAgICAgICAqIG9wdGlvbmFsIGJvb2wgdW5rbm93bkZpZWxkcyA9IDg7CiAgICAgICAqIG9ic29sZXRlLiBrZXB0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBvZiBnZW5lcmF0ZWQgY29kZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBjYWNoZWRTaXplID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2FjaGVkU2l6ZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGNhY2hlZFNpemVfXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTppb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvcmJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIERlc2NyaXB0b3JPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlc2NyaXB0b3IgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Rlc2NyaXB0b3IoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlc2NyaXB0b3IuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVzY3JpcHRvcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRlc2NyaXB0b3IuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldERlc2NyaXB0b3JCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBuZXN0ZWRfZGVzY3JpcHRvciA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWREZXNjcmlwdG9yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOZXN0ZWREZXNjcmlwdG9yKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5lc3RlZERlc2NyaXB0b3IuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIGdldE5lc3RlZERlc2NyaXB0b3IoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBuZXN0ZWRfZGVzY3JpcHRvciA9IDI7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvck9yQnVpbGRlciBnZXROZXN0ZWREZXNjcmlwdG9yT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3J9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBEZXNjcmlwdG9yIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IpCiAgICAgIERlc2NyaXB0b3JPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIERlc2NyaXB0b3IubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRGVzY3JpcHRvcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIERlc2NyaXB0b3IoKSB7CiAgICAgIGRlc2NyaXB0b3JfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRGVzY3JpcHRvcigpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0Rlc2NyaXB0b3JfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlVOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFVOS05PV04oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygxKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlVOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVkFMVUUgPSAxOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gVU5LTk9XTjsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPTzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5lc3RlZEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTppb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWREZXNjcmlwdG9yT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXNjcmlwdG9yIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzRGVzY3JpcHRvcigpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvci4KICAgICAgICovCiAgICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVzY3JpcHRvcigpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRlc2NyaXB0b3IuCiAgICAgICAqLwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldERlc2NyaXB0b3JCeXRlcygpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3J9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkRGVzY3JpcHRvciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKQogICAgICAgIE5lc3RlZERlc2NyaXB0b3JPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWREZXNjcmlwdG9yLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkRGVzY3JpcHRvcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZERlc2NyaXB0b3IoKSB7CiAgICAgICAgZGVzY3JpcHRvcl8gPSAiIjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBOZXN0ZWREZXNjcmlwdG9yKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0Rlc2NyaXB0b3JfTmVzdGVkRGVzY3JpcHRvcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU0NSSVBUT1JfRklFTERfTlVNQkVSID0gMTsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBkZXNjcmlwdG9yXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXNjcmlwdG9yIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlc2NyaXB0b3IuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZXNjcmlwdG9yXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZGVzY3JpcHRvcl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZGVzY3JpcHRvci4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RGVzY3JpcHRvckJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVzY3JpcHRvcl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBkZXNjcmlwdG9yXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIGRlc2NyaXB0b3JfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIGRlc2NyaXB0b3JfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKSBvYmo7CgogICAgICAgIGlmIChoYXNEZXNjcmlwdG9yKCkgIT0gb3RoZXIuaGFzRGVzY3JpcHRvcigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0Rlc2NyaXB0b3IoKSkgewogICAgICAgICAgaWYgKCFnZXREZXNjcmlwdG9yKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldERlc2NyaXB0b3IoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3JGb3JUeXBlKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzRGVzY3JpcHRvcigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERVNDUklQVE9SX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3J9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvcikKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yT3JCdWlsZGVyIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXNjcmlwdG9yX05lc3RlZERlc2NyaXB0b3JfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGRlc2NyaXB0b3JfID0gIiI7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0Rlc2NyaXB0b3JfTmVzdGVkRGVzY3JpcHRvcl9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuZGVzY3JpcHRvcl8gPSBkZXNjcmlwdG9yXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0Rlc2NyaXB0b3IoKSkgewogICAgICAgICAgICBkZXNjcmlwdG9yXyA9IG90aGVyLmRlc2NyaXB0b3JfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZGVzY3JpcHRvcl8gPSAiIjsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVzY3JpcHRvciBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBkZXNjcmlwdG9yLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlc2NyaXB0b3JfOwogICAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgZGVzY3JpcHRvcl8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRlc2NyaXB0b3IuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgICBnZXREZXNjcmlwdG9yQnl0ZXMoKSB7CiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlc2NyaXB0b3JfOwogICAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgICAgZGVzY3JpcHRvcl8gPSBiOwogICAgICAgICAgICByZXR1cm4gYjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZXNjcmlwdG9yIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVzY3JpcHRvcigKICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICAgIGRlc2NyaXB0b3JfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlc2NyaXB0b3IoKSB7CiAgICAgICAgICBkZXNjcmlwdG9yXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlc2NyaXB0b3IoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZGVzY3JpcHRvciB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlc2NyaXB0b3JCeXRlcygKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgICAgZGVzY3JpcHRvcl8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZERlc2NyaXB0b3I+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWREZXNjcmlwdG9yPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZERlc2NyaXB0b3IgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWREZXNjcmlwdG9yPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkRGVzY3JpcHRvcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVNDUklQVE9SX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBkZXNjcmlwdG9yXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXNjcmlwdG9yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVzY3JpcHRvci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZXNjcmlwdG9yXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBkZXNjcmlwdG9yXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZGVzY3JpcHRvci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldERlc2NyaXB0b3JCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZXNjcmlwdG9yXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgZGVzY3JpcHRvcl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVNURURfREVTQ1JJUFRPUl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBuZXN0ZWREZXNjcmlwdG9yXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBuZXN0ZWRfZGVzY3JpcHRvciA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWREZXNjcmlwdG9yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTmVzdGVkRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIG5lc3RlZF9kZXNjcmlwdG9yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWREZXNjcmlwdG9yLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgZ2V0TmVzdGVkRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG5lc3RlZERlc2NyaXB0b3JfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZERlc2NyaXB0b3JfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIG5lc3RlZF9kZXNjcmlwdG9yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvck9yQnVpbGRlciBnZXROZXN0ZWREZXNjcmlwdG9yT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbmVzdGVkRGVzY3JpcHRvcl8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkRGVzY3JpcHRvcl87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIGRlc2NyaXB0b3JfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGdldE5lc3RlZERlc2NyaXB0b3IoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgZGVzY3JpcHRvcl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBnZXROZXN0ZWREZXNjcmlwdG9yKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvcikgb2JqOwoKICAgICAgaWYgKGhhc0Rlc2NyaXB0b3IoKSAhPSBvdGhlci5oYXNEZXNjcmlwdG9yKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Rlc2NyaXB0b3IoKSkgewogICAgICAgIGlmICghZ2V0RGVzY3JpcHRvcigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGVzY3JpcHRvcigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNOZXN0ZWREZXNjcmlwdG9yKCkgIT0gb3RoZXIuaGFzTmVzdGVkRGVzY3JpcHRvcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNOZXN0ZWREZXNjcmlwdG9yKCkpIHsKICAgICAgICBpZiAoIWdldE5lc3RlZERlc2NyaXB0b3IoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE5lc3RlZERlc2NyaXB0b3IoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRGVzY3JpcHRvcigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVTQ1JJUFRPUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc05lc3RlZERlc2NyaXB0b3IoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5FU1RFRF9ERVNDUklQVE9SX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXROZXN0ZWREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yT3JCdWlsZGVyIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXROZXN0ZWREZXNjcmlwdG9yRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBkZXNjcmlwdG9yXyA9ICIiOwogICAgICAgIG5lc3RlZERlc2NyaXB0b3JfID0gbnVsbDsKICAgICAgICBpZiAobmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG5lc3RlZERlc2NyaXB0b3JCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvcih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVzY3JpcHRvcl8gPSBkZXNjcmlwdG9yXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5uZXN0ZWREZXNjcmlwdG9yXyA9IG5lc3RlZERlc2NyaXB0b3JCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBuZXN0ZWREZXNjcmlwdG9yXwogICAgICAgICAgICAgIDogbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3Igb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzRGVzY3JpcHRvcigpKSB7CiAgICAgICAgICBkZXNjcmlwdG9yXyA9IG90aGVyLmRlc2NyaXB0b3JfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNOZXN0ZWREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIG1lcmdlTmVzdGVkRGVzY3JpcHRvcihvdGhlci5nZXROZXN0ZWREZXNjcmlwdG9yKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdG9yXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TmVzdGVkRGVzY3JpcHRvckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGRlc2NyaXB0b3JfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlc2NyaXB0b3IgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlc2NyaXB0b3IuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVzY3JpcHRvcl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBkZXNjcmlwdG9yXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVzY3JpcHRvciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZGVzY3JpcHRvci4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldERlc2NyaXB0b3JCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlc2NyaXB0b3JfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBkZXNjcmlwdG9yXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZXNjcmlwdG9yID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVzY3JpcHRvciB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlc2NyaXB0b3IoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBkZXNjcmlwdG9yXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZXNjcmlwdG9yKCkgewogICAgICAgIGRlc2NyaXB0b3JfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGVzY3JpcHRvcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlc2NyaXB0b3IgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZGVzY3JpcHRvciB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlc2NyaXB0b3JCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZGVzY3JpcHRvcl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkRGVzY3JpcHRvcl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvck9yQnVpbGRlcj4gbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBuZXN0ZWRfZGVzY3JpcHRvciA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZERlc2NyaXB0b3IgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmVzdGVkRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbmVzdGVkRGVzY3JpcHRvci4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBnZXROZXN0ZWREZXNjcmlwdG9yKCkgewogICAgICAgIGlmIChuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5lc3RlZERlc2NyaXB0b3JfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZERlc2NyaXB0b3JfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5lc3RlZERlc2NyaXB0b3IoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgdmFsdWUpIHsKICAgICAgICBpZiAobmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbmVzdGVkRGVzY3JpcHRvcl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5lc3RlZERlc2NyaXB0b3IoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbmVzdGVkRGVzY3JpcHRvcl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTmVzdGVkRGVzY3JpcHRvcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciB2YWx1ZSkgewogICAgICAgIGlmIChuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApICYmCiAgICAgICAgICAgIG5lc3RlZERlc2NyaXB0b3JfICE9IG51bGwgJiYKICAgICAgICAgICAgbmVzdGVkRGVzY3JpcHRvcl8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0TmVzdGVkRGVzY3JpcHRvckJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmVzdGVkRGVzY3JpcHRvcl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChuZXN0ZWREZXNjcmlwdG9yXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTmVzdGVkRGVzY3JpcHRvcigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgbmVzdGVkRGVzY3JpcHRvcl8gPSBudWxsOwogICAgICAgIGlmIChuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbmVzdGVkRGVzY3JpcHRvckJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG5lc3RlZERlc2NyaXB0b3JCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yIG5lc3RlZF9kZXNjcmlwdG9yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IuQnVpbGRlciBnZXROZXN0ZWREZXNjcmlwdG9yQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE5lc3RlZERlc2NyaXB0b3JGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IgbmVzdGVkX2Rlc2NyaXB0b3IgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvck9yQnVpbGRlciBnZXROZXN0ZWREZXNjcmlwdG9yT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5lc3RlZERlc2NyaXB0b3JCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBuZXN0ZWREZXNjcmlwdG9yXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZERlc2NyaXB0b3JfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciBuZXN0ZWRfZGVzY3JpcHRvciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvci5OZXN0ZWREZXNjcmlwdG9yT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE5lc3RlZERlc2NyaXB0b3JGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG5lc3RlZERlc2NyaXB0b3JCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IuTmVzdGVkRGVzY3JpcHRvciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3IuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXNjcmlwdG9yLk5lc3RlZERlc2NyaXB0b3JPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXROZXN0ZWREZXNjcmlwdG9yKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBuZXN0ZWREZXNjcmlwdG9yXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXN0ZWREZXNjcmlwdG9yQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlc2NyaXB0b3IoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPERlc2NyaXB0b3I+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RGVzY3JpcHRvcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIERlc2NyaXB0b3IgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxEZXNjcmlwdG9yPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPERlc2NyaXB0b3I+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVzY3JpcHRvciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFBhcnNlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5QYXJzZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuUGFyc2VyLlBhcnNlckVudW0gcGFyc2VyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBhcnNlciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUGFyc2VyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5QYXJzZXIuUGFyc2VyRW51bSBwYXJzZXIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBhcnNlci4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuUGFyc2VyRW51bSBnZXRQYXJzZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuUGFyc2VyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUGFyc2VyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLlBhcnNlcikKICAgICAgUGFyc2VyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQYXJzZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUGFyc2VyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUGFyc2VyKCkgewogICAgICBwYXJzZXJfID0gMDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBQYXJzZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19QYXJzZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19QYXJzZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5QYXJzZXIuUGFyc2VyRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gUGFyc2VyRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlVOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFVOS05PV04oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5QQVJTRVIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIFBBUlNFUigxKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlVOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+UEFSU0VSID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVJTRVJfVkFMVUUgPSAxOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgUGFyc2VyRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgUGFyc2VyRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gVU5LTk9XTjsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIFBBUlNFUjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFBhcnNlckVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBQYXJzZXJFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8UGFyc2VyRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFBhcnNlckVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFBhcnNlckVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXJzZXJFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFBhcnNlckVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBQYXJzZXJFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuUGFyc2VyLlBhcnNlckVudW0pCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBUlNFUl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgcGFyc2VyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5QYXJzZXIuUGFyc2VyRW51bSBwYXJzZXIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGFyc2VyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNQYXJzZXIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlBhcnNlci5QYXJzZXJFbnVtIHBhcnNlciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGFyc2VyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5QYXJzZXJFbnVtIGdldFBhcnNlcigpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuUGFyc2VyRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5QYXJzZXJFbnVtLmZvck51bWJlcihwYXJzZXJfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuUGFyc2VyRW51bS5VTktOT1dOIDogcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCBwYXJzZXJfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEsIHBhcnNlcl8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlcikgb2JqOwoKICAgICAgaWYgKGhhc1BhcnNlcigpICE9IG90aGVyLmhhc1BhcnNlcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQYXJzZXIoKSkgewogICAgICAgIGlmIChwYXJzZXJfICE9IG90aGVyLnBhcnNlcl8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNQYXJzZXIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBUlNFUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFyc2VyXzsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5QYXJzZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5QYXJzZXIpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfUGFyc2VyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1BhcnNlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgcGFyc2VyXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1BhcnNlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBhcnNlcl8gPSBwYXJzZXJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uUGFyc2VyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzUGFyc2VyKCkpIHsKICAgICAgICAgIHNldFBhcnNlcihvdGhlci5nZXRQYXJzZXIoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5QYXJzZXJFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5QYXJzZXJFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHBhcnNlcl8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IHBhcnNlcl8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlBhcnNlci5QYXJzZXJFbnVtIHBhcnNlciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBhcnNlciBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1BhcnNlcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5QYXJzZXIuUGFyc2VyRW51bSBwYXJzZXIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGFyc2VyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuUGFyc2VyRW51bSBnZXRQYXJzZXIoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuUGFyc2VyRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5QYXJzZXJFbnVtLmZvck51bWJlcihwYXJzZXJfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlci5QYXJzZXJFbnVtLlVOS05PV04gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5QYXJzZXIuUGFyc2VyRW51bSBwYXJzZXIgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYXJzZXIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXJzZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIuUGFyc2VyRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHBhcnNlcl8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlBhcnNlci5QYXJzZXJFbnVtIHBhcnNlciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhcnNlcigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgcGFyc2VyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuUGFyc2VyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTppb19wcm90b2NvbF90ZXN0cy5QYXJzZXIpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlciBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlBhcnNlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQYXJzZXI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UGFyc2VyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUGFyc2VyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UGFyc2VyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFBhcnNlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5QYXJzZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBEZXByZWNhdGVkT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDEgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bztsPTExNgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgYm9vbGVhbiBoYXNGaWVsZDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQxIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG87bD0xMTYKICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMS4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIGludCBnZXRGaWVsZDEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLlRlc3RFbnVtIGZpZWxkMiA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBpb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLmZpZWxkMiBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE3CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBib29sZWFuIGhhc0ZpZWxkMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5UZXN0RW51bSBmaWVsZDIgPSAyIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDIgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bztsPTExNwogICAgICogQHJldHVybiBUaGUgZmllbGQyLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkLlRlc3RFbnVtIGdldEZpZWxkMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQzIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG87bD0xMTgKICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIGJvb2xlYW4gaGFzRmllbGQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGZpZWxkMyA9IDMgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBpb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLmZpZWxkMyBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE4CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0RmllbGQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGZpZWxkMyA9IDMgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGQzT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBEZXByZWNhdGVkIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQpCiAgICAgIERlcHJlY2F0ZWRPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIERlcHJlY2F0ZWQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRGVwcmVjYXRlZChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIERlcHJlY2F0ZWQoKSB7CiAgICAgIGZpZWxkMl8gPSAwOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IERlcHJlY2F0ZWQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXByZWNhdGVkX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVwcmVjYXRlZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5UZXN0RW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gVGVzdEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBVTktOT1dOKDApLAogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBGT08oMSksCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0IGlmICYjNjQ7RGVwcmVjYXRlZCBhbm5vdGF0aW9uIGNvbmZsaWN0cyB3aXRoIERlcHJlY2F0ZWQgbWVzc2FnZSBuYW1lLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+QkFSID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBCQVIoMiksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgaWYgJiM2NDtEZXByZWNhdGVkIGFubm90YXRpb24gY29uZmxpY3RzIHdpdGggRGVwcmVjYXRlZCBtZXNzYWdlIG5hbWUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5CQVIgPSAyIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDI7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFVOS05PV047CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBCQVI7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIFRlc3RFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBUZXN0RW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVGVzdEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGVzdEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBUZXN0RW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuVGVzdEVudW0pCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgZmllbGQxXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMSA9IDEgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBpb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLmZpZWxkMSBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE2CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQxIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG87bD0xMTYKICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBpbnQgZ2V0RmllbGQxKCkgewogICAgICByZXR1cm4gZmllbGQxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGZpZWxkMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5UZXN0RW51bSBmaWVsZDIgPSAyIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDIgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bztsPTExNwogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuVGVzdEVudW0gZmllbGQyID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQyIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG87bD0xMTcKICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5UZXN0RW51bSBnZXRGaWVsZDIoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkMl8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuVGVzdEVudW0uVU5LTk9XTiA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGZpZWxkM187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGZpZWxkMyA9IDMgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBpb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLmZpZWxkMyBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE4CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQzIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG87bD0xMTgKICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0RmllbGQzKCkgewogICAgICByZXR1cm4gZmllbGQzXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGQzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGQzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGQzXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGQzXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGZpZWxkMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMiwgZmllbGQyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCBnZXRGaWVsZDMoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgZmllbGQxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIsIGZpZWxkMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBnZXRGaWVsZDMoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkKSBvYmo7CgogICAgICBpZiAoaGFzRmllbGQxKCkgIT0gb3RoZXIuaGFzRmllbGQxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkMigpICE9IG90aGVyLmhhc0ZpZWxkMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZDIoKSkgewogICAgICAgIGlmIChmaWVsZDJfICE9IG90aGVyLmZpZWxkMl8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQzKCkgIT0gb3RoZXIuaGFzRmllbGQzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkMygpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZDMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDEoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkMl87CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVwcmVjYXRlZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXByZWNhdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEZpZWxkM0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZmllbGQxXyA9IDA7CiAgICAgICAgZmllbGQyXyA9IDA7CiAgICAgICAgZmllbGQzXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkM0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0RlcHJlY2F0ZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkMV8gPSBmaWVsZDFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkMl8gPSBmaWVsZDJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkM18gPSBmaWVsZDNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmaWVsZDNfCiAgICAgICAgICAgICAgOiBmaWVsZDNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkMSgpKSB7CiAgICAgICAgICBzZXRGaWVsZDEob3RoZXIuZ2V0RmllbGQxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGQyKCkpIHsKICAgICAgICAgIHNldEZpZWxkMihvdGhlci5nZXRGaWVsZDIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZDMoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZDMob3RoZXIuZ2V0RmllbGQzKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGZpZWxkMV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuVGVzdEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRGVwcmVjYXRlZC5UZXN0RW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBmaWVsZDJfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZDNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGZpZWxkMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDEgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE2CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMSA9IDEgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQxIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bztsPTExNgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgaW50IGdldEZpZWxkMSgpIHsKICAgICAgICByZXR1cm4gZmllbGQxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDEgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE2CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMShpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDEgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE2CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZmllbGQxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkMl8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuVGVzdEVudW0gZmllbGQyID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDIgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE3CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLlRlc3RFbnVtIGZpZWxkMiA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQyIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bztsPTExNwogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkLlRlc3RFbnVtIGdldEZpZWxkMigpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZDJfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuVGVzdEVudW0uVU5LTk9XTiA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuVGVzdEVudW0gZmllbGQyID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDIgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE3CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBmaWVsZDJfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLlRlc3RFbnVtIGZpZWxkMiA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBkZXByZWNhdGVkIGlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQuZmllbGQyIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2JhZF9pZGVudGlmaWVycy5wcm90bztsPTExNwogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGZpZWxkMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBmaWVsZDNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXI+IGZpZWxkM0J1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5maWVsZDMgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvO2w9MTE4CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBmaWVsZDMgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBpb19wcm90b2NvbF90ZXN0cy5EZXByZWNhdGVkLmZpZWxkMyBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG87bD0xMTgKICAgICAgICogQHJldHVybiBUaGUgZmllbGQzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0RmllbGQzKCkgewogICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGQzXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGQzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkM0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGZpZWxkMyA9IDMgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQzKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkM18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGQzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGQzXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZDNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBmaWVsZDMgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGQzKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGQzXyAhPSBudWxsICYmCiAgICAgICAgICAgIGZpZWxkM18gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkM0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQzXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZDNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGQzXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGZpZWxkMyA9IDMgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGZpZWxkM18gPSBudWxsOwogICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZDNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZDNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBmaWVsZDMgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZDNCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RmllbGQzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBmaWVsZDMgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGQzT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGQzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGQzXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZDNfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZmllbGQzID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZDNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkM0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGQzKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZDNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkM0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkRlcHJlY2F0ZWQpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5EZXByZWNhdGVkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxEZXByZWNhdGVkPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPERlcHJlY2F0ZWQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZXByZWNhdGVkIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RGVwcmVjYXRlZD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxEZXByZWNhdGVkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRlcHJlY2F0ZWQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBPdmVycmlkZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5PdmVycmlkZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG92ZXJyaWRlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG92ZXJyaWRlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPdmVycmlkZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdmVycmlkZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3ZlcnJpZGUuCiAgICAgKi8KICAgIGludCBnZXRPdmVycmlkZSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5PdmVycmlkZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLk92ZXJyaWRlKQogICAgICBPdmVycmlkZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgT3ZlcnJpZGUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgT3ZlcnJpZGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBPdmVycmlkZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX092ZXJyaWRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT3ZlcnJpZGVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVkVSUklERV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3ZlcnJpZGVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3ZlcnJpZGUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3ZlcnJpZGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPdmVycmlkZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdmVycmlkZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3ZlcnJpZGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3ZlcnJpZGUoKSB7CiAgICAgIHJldHVybiBvdmVycmlkZV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBvdmVycmlkZV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG92ZXJyaWRlXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlKSBvYmo7CgogICAgICBpZiAoaGFzT3ZlcnJpZGUoKSAhPSBvdGhlci5oYXNPdmVycmlkZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdmVycmlkZSgpKSB7CiAgICAgICAgaWYgKGdldE92ZXJyaWRlKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3ZlcnJpZGUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc092ZXJyaWRlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPVkVSUklERV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3ZlcnJpZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLk92ZXJyaWRlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuT3ZlcnJpZGUpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19PdmVycmlkZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19PdmVycmlkZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3ZlcnJpZGVfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT3ZlcnJpZGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3ZlcnJpZGVfID0gb3ZlcnJpZGVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PdmVycmlkZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPdmVycmlkZSgpKSB7CiAgICAgICAgICBzZXRPdmVycmlkZShvdGhlci5nZXRPdmVycmlkZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvdmVycmlkZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG92ZXJyaWRlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdmVycmlkZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG92ZXJyaWRlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3ZlcnJpZGUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdmVycmlkZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvdmVycmlkZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPdmVycmlkZSgpIHsKICAgICAgICByZXR1cm4gb3ZlcnJpZGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdmVycmlkZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG92ZXJyaWRlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3ZlcnJpZGUoaW50IHZhbHVlKSB7CgogICAgICAgIG92ZXJyaWRlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3ZlcnJpZGUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPdmVycmlkZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3ZlcnJpZGVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5PdmVycmlkZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuT3ZlcnJpZGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk92ZXJyaWRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPdmVycmlkZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxPdmVycmlkZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE92ZXJyaWRlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3ZlcnJpZGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3ZlcnJpZGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT3ZlcnJpZGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBPYmplY3RPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuT2JqZWN0KQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb2JqZWN0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9iamVjdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT2JqZWN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9iamVjdCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb2JqZWN0LgogICAgICovCiAgICBpbnQgZ2V0T2JqZWN0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX29iamVjdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdPYmplY3QgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cmluZ09iamVjdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX29iamVjdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyaW5nT2JqZWN0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ09iamVjdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX29iamVjdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ09iamVjdC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nT2JqZWN0Qnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuT2JqZWN0fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT2JqZWN0IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLk9iamVjdCkKICAgICAgT2JqZWN0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBPYmplY3QubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgT2JqZWN0KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgT2JqZWN0KCkgewogICAgICBzdHJpbmdPYmplY3RfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgT2JqZWN0KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT2JqZWN0X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT2JqZWN0X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPQkpFQ1RfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG9iamVjdF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvYmplY3QgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb2JqZWN0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT2JqZWN0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9iamVjdCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb2JqZWN0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9iamVjdCgpIHsKICAgICAgcmV0dXJuIG9iamVjdF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX09CSkVDVF9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nT2JqZWN0XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX29iamVjdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdPYmplY3QgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdPYmplY3QoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19vYmplY3QgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ09iamVjdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nT2JqZWN0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ09iamVjdF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyaW5nT2JqZWN0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfb2JqZWN0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nT2JqZWN0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nT2JqZWN0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nT2JqZWN0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyaW5nT2JqZWN0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb2JqZWN0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBzdHJpbmdPYmplY3RfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBvYmplY3RfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIHN0cmluZ09iamVjdF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCkgb2JqOwoKICAgICAgaWYgKGhhc09iamVjdCgpICE9IG90aGVyLmhhc09iamVjdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPYmplY3QoKSkgewogICAgICAgIGlmIChnZXRPYmplY3QoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPYmplY3QoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHJpbmdPYmplY3QoKSAhPSBvdGhlci5oYXNTdHJpbmdPYmplY3QoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3RyaW5nT2JqZWN0KCkpIHsKICAgICAgICBpZiAoIWdldFN0cmluZ09iamVjdCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nT2JqZWN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT2JqZWN0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPQkpFQ1RfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9iamVjdCgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHJpbmdPYmplY3QoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19PQkpFQ1RfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cmluZ09iamVjdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuT2JqZWN0fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuT2JqZWN0KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX09iamVjdF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19PYmplY3RfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG9iamVjdF8gPSAwOwogICAgICAgIHN0cmluZ09iamVjdF8gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT2JqZWN0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub2JqZWN0XyA9IG9iamVjdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nT2JqZWN0XyA9IHN0cmluZ09iamVjdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLk9iamVjdCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3Qpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3Qgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPYmplY3QoKSkgewogICAgICAgICAgc2V0T2JqZWN0KG90aGVyLmdldE9iamVjdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cmluZ09iamVjdCgpKSB7CiAgICAgICAgICBzdHJpbmdPYmplY3RfID0gb3RoZXIuc3RyaW5nT2JqZWN0XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9iamVjdF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgc3RyaW5nT2JqZWN0XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9iamVjdF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb2JqZWN0ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb2JqZWN0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT2JqZWN0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb2JqZWN0ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9iamVjdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPYmplY3QoKSB7CiAgICAgICAgcmV0dXJuIG9iamVjdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9iamVjdCA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9iamVjdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9iamVjdChpbnQgdmFsdWUpIHsKCiAgICAgICAgb2JqZWN0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb2JqZWN0ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT2JqZWN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvYmplY3RfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cmluZ09iamVjdF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfb2JqZWN0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nT2JqZWN0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ09iamVjdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfb2JqZWN0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ09iamVjdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ09iamVjdCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ09iamVjdF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHJpbmdPYmplY3RfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfb2JqZWN0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdPYmplY3QuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdPYmplY3RCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ09iamVjdF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cmluZ09iamVjdF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX29iamVjdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ09iamVjdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZ09iamVjdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cmluZ09iamVjdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfb2JqZWN0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nT2JqZWN0KCkgewogICAgICAgIHN0cmluZ09iamVjdF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHJpbmdPYmplY3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfb2JqZWN0ID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cmluZ09iamVjdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZ09iamVjdEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHJpbmdPYmplY3RfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLk9iamVjdCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuT2JqZWN0KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5PYmplY3QoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T2JqZWN0PgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9iamVjdD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE9iamVjdCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9iamVjdD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPYmplY3Q+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uT2JqZWN0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgU3RyaW5nT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmlvX3Byb3RvY29sX3Rlc3RzLlN0cmluZykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmcgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHJpbmdCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5TdHJpbmd9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmcgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuU3RyaW5nKQogICAgICBTdHJpbmdPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFN0cmluZy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBTdHJpbmcoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBTdHJpbmcoKSB7CiAgICAgIHN0cmluZ18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19TdHJpbmdfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19TdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cmluZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBzdHJpbmdfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBzdHJpbmdfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcpIG9iajsKCiAgICAgIGlmIChoYXNTdHJpbmcoKSAhPSBvdGhlci5oYXNTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldFN0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzU3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuU3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuU3RyaW5nKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1N0cmluZ19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19TdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHN0cmluZ18gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfU3RyaW5nX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXyA9IHN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5TdHJpbmcuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNTdHJpbmcoKSkgewogICAgICAgICAgc3RyaW5nXyA9IG90aGVyLnN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgc3RyaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cmluZ18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmcoKSB7CiAgICAgICAgc3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5TdHJpbmcpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlN0cmluZykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uU3RyaW5nKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN0cmluZz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxTdHJpbmc+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBTdHJpbmcgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdHJpbmc+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3RyaW5nPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlN0cmluZyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEludGVnZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuSW50ZWdlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludGVnZXIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50ZWdlciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzSW50ZWdlcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRlZ2VyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnRlZ2VyLgogICAgICovCiAgICBpbnQgZ2V0SW50ZWdlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5JbnRlZ2VyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgSW50ZWdlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5JbnRlZ2VyKQogICAgICBJbnRlZ2VyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBJbnRlZ2VyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEludGVnZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBJbnRlZ2VyKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEludGVnZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19JbnRlZ2VyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfSW50ZWdlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlRFR0VSX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBpbnRlZ2VyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludGVnZXIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50ZWdlciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludGVnZXIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50ZWdlciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50ZWdlci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRlZ2VyKCkgewogICAgICByZXR1cm4gaW50ZWdlcl87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBpbnRlZ2VyXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgaW50ZWdlcl8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlcikgb2JqOwoKICAgICAgaWYgKGhhc0ludGVnZXIoKSAhPSBvdGhlci5oYXNJbnRlZ2VyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ludGVnZXIoKSkgewogICAgICAgIGlmIChnZXRJbnRlZ2VyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0SW50ZWdlcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzSW50ZWdlcigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5URUdFUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50ZWdlcigpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5JbnRlZ2VyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuSW50ZWdlcikKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfSW50ZWdlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19JbnRlZ2VyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlZ2VyXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ludGVnZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludGVnZXJfID0gaW50ZWdlcl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkludGVnZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzSW50ZWdlcigpKSB7CiAgICAgICAgICBzZXRJbnRlZ2VyKG90aGVyLmdldEludGVnZXIoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50ZWdlcl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGludGVnZXJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludGVnZXIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRlZ2VyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50ZWdlcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludGVnZXIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50ZWdlci4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRlZ2VyKCkgewogICAgICAgIHJldHVybiBpbnRlZ2VyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50ZWdlciA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludGVnZXIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnRlZ2VyKGludCB2YWx1ZSkgewoKICAgICAgICBpbnRlZ2VyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50ZWdlciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludGVnZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVnZXJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5JbnRlZ2VyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTppb19wcm90b2NvbF90ZXN0cy5JbnRlZ2VyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uSW50ZWdlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50ZWdlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxJbnRlZ2VyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgSW50ZWdlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEludGVnZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50ZWdlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5JbnRlZ2VyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTG9uZ09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5Mb25nKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbG9uZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGxvbmcgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmcuCiAgICAgKi8KICAgIGludCBnZXRMb25nKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkxvbmd9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBMb25nIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkxvbmcpCiAgICAgIExvbmdPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIExvbmcubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTG9uZyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIExvbmcoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTG9uZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0xvbmdfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Mb25nX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGxvbmdfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbG9uZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBsb25nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldExvbmcoKSB7CiAgICAgIHJldHVybiBsb25nXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGxvbmdfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBsb25nXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nKSBvYmo7CgogICAgICBpZiAoaGFzTG9uZygpICE9IG90aGVyLmhhc0xvbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTG9uZygpKSB7CiAgICAgICAgaWYgKGdldExvbmcoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRMb25nKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNMb25nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBMT05HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRMb25nKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkxvbmd9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5Mb25nKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZ09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Mb25nX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0xvbmdfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGxvbmdfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfTG9uZ19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ18gPSBsb25nXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uTG9uZyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNMb25nKCkpIHsKICAgICAgICAgIHNldExvbmcob3RoZXIuZ2V0TG9uZygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBsb25nXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgbG9uZ18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbG9uZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbG9uZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldExvbmcoKSB7CiAgICAgICAgcmV0dXJuIGxvbmdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBsb25nID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmcoaW50IHZhbHVlKSB7CgogICAgICAgIGxvbmdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBsb25nID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgbG9uZ18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkxvbmcpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkxvbmcpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Mb25nKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMb25nPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPExvbmc+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBMb25nIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TG9uZz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMb25nPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkxvbmcgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBGbG9hdE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5GbG9hdCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldEZsb2F0KCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLkZsb2F0fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmxvYXQgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuRmxvYXQpCiAgICAgIEZsb2F0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGbG9hdC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGbG9hdChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZsb2F0KCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZsb2F0KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19GbG9hdF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMT0FUX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGZsb2F0IGZsb2F0XyA9IDBGOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zsb2F0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZsb2F0KCkgewogICAgICByZXR1cm4gZmxvYXRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMSwgZmxvYXRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgxLCBmbG9hdF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCkgb2JqOwoKICAgICAgaWYgKGhhc0Zsb2F0KCkgIT0gb3RoZXIuaGFzRmxvYXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmxvYXQoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0RmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGbG9hdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgZ2V0RmxvYXQoKSk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZsb2F0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5GbG9hdH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLkZsb2F0KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZsb2F0XyA9IDBGOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19GbG9hdF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZsb2F0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mbG9hdF8gPSBmbG9hdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZsb2F0KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZsb2F0KW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0Zsb2F0KCkpIHsKICAgICAgICAgIHNldEZsb2F0KG90aGVyLmdldEZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEzOiB7CiAgICAgICAgICAgICAgICBmbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGZsb2F0IGZsb2F0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZsb2F0KCkgewogICAgICAgIHJldHVybiBmbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0ID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBmbG9hdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZsb2F0XyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkZsb2F0KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTppb19wcm90b2NvbF90ZXN0cy5GbG9hdCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRmxvYXQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZsb2F0PgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZsb2F0PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRmxvYXQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGbG9hdD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGbG9hdD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5GbG9hdCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIERvdWJsZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5Eb3VibGUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZG91YmxlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBkb3VibGUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRvdWJsZS4KICAgICAqLwogICAgZG91YmxlIGdldERvdWJsZSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5Eb3VibGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBEb3VibGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuRG91YmxlKQogICAgICBEb3VibGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIERvdWJsZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBEb3VibGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBEb3VibGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRG91YmxlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRG91YmxlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRG91YmxlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET1VCTEVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgZG91YmxlIGRvdWJsZV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRvdWJsZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkb3VibGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEb3VibGUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRvdWJsZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldERvdWJsZSgpIHsKICAgICAgcmV0dXJuIGRvdWJsZV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoMSwgZG91YmxlXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDEsIGRvdWJsZV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSkgb2JqOwoKICAgICAgaWYgKGhhc0RvdWJsZSgpICE9IG90aGVyLmhhc0RvdWJsZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEb3VibGUoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RG91YmxlKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldERvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0RvdWJsZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RG91YmxlKCkpKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5Eb3VibGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5Eb3VibGUpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRG91YmxlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0RvdWJsZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZG91YmxlXyA9IDBEOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Eb3VibGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Eb3VibGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kb3VibGVfID0gZG91YmxlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0RvdWJsZSgpKSB7CiAgICAgICAgICBzZXREb3VibGUob3RoZXIuZ2V0RG91YmxlKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDk6IHsKICAgICAgICAgICAgICAgIGRvdWJsZV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOQogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGRvdWJsZSBkb3VibGVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBkb3VibGUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkb3VibGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZG91YmxlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRvdWJsZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXREb3VibGUoKSB7CiAgICAgICAgcmV0dXJuIGRvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBkb3VibGUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGRvdWJsZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBkb3VibGUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGRvdWJsZV8gPSAwRDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5Eb3VibGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLkRvdWJsZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRG91YmxlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPERvdWJsZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxEb3VibGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBEb3VibGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxEb3VibGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RG91YmxlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkRvdWJsZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBpbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgaW50MzJGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldEludDMyRmllbGQxTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBpbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgaW50MzJGaWVsZC4KICAgICAqLwogICAgaW50IGdldEludDMyRmllbGQxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgaW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRJbnQzMkZpZWxkMShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gZW51bV9maWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bUZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0+IGdldEVudW1GaWVsZDJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGVudW1GaWVsZC4KICAgICAqLwogICAgaW50IGdldEVudW1GaWVsZDJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW1GaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBnZXRFbnVtRmllbGQyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRTdHJpbmdGaWVsZDNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHN0cmluZ0ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nRmllbGQzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nRmllbGQzKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmdGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cmluZ0ZpZWxkM0J5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBieXRlc19maWVsZCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgYnl0ZXNGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRCeXRlc0ZpZWxkNExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgYnl0ZXNfZmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGJ5dGVzRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRCeXRlc0ZpZWxkNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGJ5dGVzX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Qnl0ZXNGaWVsZDQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gCiAgICAgICAgZ2V0TWVzc2FnZUZpZWxkNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldE1lc3NhZ2VGaWVsZDUoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNZXNzYWdlRmllbGQ1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0TWVzc2FnZUZpZWxkNU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZDVPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludDMyX2ZpZWxkX2NvdW50ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQzMkZpZWxkQ291bnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ludDMyRmllbGRDb3VudDExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludDMyX2ZpZWxkX2NvdW50ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZENvdW50LgogICAgICovCiAgICBpbnQgZ2V0SW50MzJGaWVsZENvdW50MTEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGRfY291bnQgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudW1GaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNFbnVtRmllbGRDb3VudDEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGRfY291bnQgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGRDb3VudC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGdldEVudW1GaWVsZENvdW50MTIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGRfY291bnQgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ0ZpZWxkQ291bnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cmluZ0ZpZWxkQ291bnQxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkX2NvdW50ID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyaW5nRmllbGRDb3VudC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdGaWVsZENvdW50MTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZF9jb3VudCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZENvdW50LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHJpbmdGaWVsZENvdW50MTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgYnl0ZXNfZmllbGRfY291bnQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJ5dGVzRmllbGRDb3VudCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQnl0ZXNGaWVsZENvdW50MTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgYnl0ZXNfZmllbGRfY291bnQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlc0ZpZWxkQ291bnQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRCeXRlc0ZpZWxkQ291bnQxNCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlRmllbGRDb3VudCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTWVzc2FnZUZpZWxkQ291bnQxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGRfY291bnQgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlRmllbGRDb3VudC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0TWVzc2FnZUZpZWxkQ291bnQxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGRfY291bnQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZENvdW50MTVPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBpbnQzMkZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJGaWVsZDIxTGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBJbnQzMkZpZWxkID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgaW50MzJGaWVsZC4KICAgICAqLwogICAgaW50IGdldEludDMyRmllbGQyMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGludDMyRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0SW50MzJGaWVsZDIxKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBFbnVtRmllbGQgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtRmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bT4gZ2V0RW51bUZpZWxkMjJMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIEVudW1GaWVsZCA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGVudW1GaWVsZC4KICAgICAqLwogICAgaW50IGdldEVudW1GaWVsZDIyQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gRW51bUZpZWxkID0gMjI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gZ2V0RW51bUZpZWxkMjIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHN0cmluZ0ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFN0cmluZ0ZpZWxkMjNMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHN0cmluZ0ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nRmllbGQyM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgc3RyaW5nRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkMjMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nRmllbGQyM0J5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBCeXRlc0ZpZWxkID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgYnl0ZXNGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRCeXRlc0ZpZWxkMjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIEJ5dGVzRmllbGQgPSAyNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBieXRlc0ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0Qnl0ZXNGaWVsZDI0Q291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgQnl0ZXNGaWVsZCA9IDI0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRCeXRlc0ZpZWxkMjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gCiAgICAgICAgZ2V0TWVzc2FnZUZpZWxkMjVMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBnZXRNZXNzYWdlRmllbGQyNShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1lc3NhZ2VGaWVsZDI1Q291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0TWVzc2FnZUZpZWxkMjVPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlciBnZXRNZXNzYWdlRmllbGQyNU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgZmllbGQgY29uZmxpY3RzIHdpdGggImludDMyX2ZpZWxkIiBhcyB0aGV5IGJvdGggZ2VuZXJhdGUKICAgICAqIHRoZSBtZXRob2QgZ2V0SW50MzJGaWVsZExpc3QoKS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGludDMyX2ZpZWxkX2xpc3QgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludDMyRmllbGRMaXN0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnQzMkZpZWxkTGlzdDMxKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIGZpZWxkIGNvbmZsaWN0cyB3aXRoICJpbnQzMl9maWVsZCIgYXMgdGhleSBib3RoIGdlbmVyYXRlCiAgICAgKiB0aGUgbWV0aG9kIGdldEludDMyRmllbGRMaXN0KCkuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpbnQzMl9maWVsZF9saXN0ID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZExpc3QuCiAgICAgKi8KICAgIGludCBnZXRJbnQzMkZpZWxkTGlzdDMxKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZmllbGQgcGFpcnMgaGF2ZSB0aGUgc2FtZSBKYXZhIGNvbnZlcnRlZCBuYW1lCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfbmFtZSA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE5hbWUzMigpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZmllbGQgcGFpcnMgaGF2ZSB0aGUgc2FtZSBKYXZhIGNvbnZlcnRlZCBuYW1lCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfbmFtZSA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE5hbWUzMigpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZmllbGQgcGFpcnMgaGF2ZSB0aGUgc2FtZSBKYXZhIGNvbnZlcnRlZCBuYW1lCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfbmFtZSA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZE5hbWUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkTmFtZTMyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9fbmFtZSA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE5hbWUzMygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfX25hbWUgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGROYW1lMzMoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX19uYW1lID0gMzM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkTmFtZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGROYW1lMzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzJjb25mbGljdCA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgMmNvbmZsaWN0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXMyQ29uZmxpY3QzNCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfMmNvbmZsaWN0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgMmNvbmZsaWN0LgogICAgICovCiAgICBpbnQgZ2V0MkNvbmZsaWN0MzQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF9fMmNvbmZsaWN0ID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAyY29uZmxpY3QgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhczJDb25mbGljdDM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF9fMmNvbmZsaWN0ID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgMmNvbmZsaWN0LgogICAgICovCiAgICBpbnQgZ2V0MkNvbmZsaWN0MzUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGludDY0X2ZpZWxkID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgaW50NjRGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEludDY0RmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGludDY0X2ZpZWxkID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgaW50NjRGaWVsZC4KICAgICAqLwogICAgaW50IGdldEludDY0RmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgaW50NjRGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0SW50NjRGaWVsZChpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXM+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzKQogICAgICBUZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzKCkgewogICAgICBpbnQzMkZpZWxkMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZW51bUZpZWxkMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHN0cmluZ0ZpZWxkM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBieXRlc0ZpZWxkNF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgbWVzc2FnZUZpZWxkNV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGVudW1GaWVsZENvdW50MTJfID0gMDsKICAgICAgc3RyaW5nRmllbGRDb3VudDEzXyA9ICIiOwogICAgICBieXRlc0ZpZWxkQ291bnQxNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIGludDMyRmllbGQyMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZW51bUZpZWxkMjJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBzdHJpbmdGaWVsZDIzXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIGJ5dGVzRmllbGQyNF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgbWVzc2FnZUZpZWxkMjVfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBmaWVsZE5hbWUzMl8gPSAiIjsKICAgICAgZmllbGROYW1lMzNfID0gIiI7CiAgICAgIGludDY0RmllbGRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gVGVzdEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBVTktOT1dOKDApLAogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBGT08oMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gVU5LTk9XTjsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPTzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgVGVzdEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFRlc3RFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBUZXN0RW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUZXN0RW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIFRlc3RFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSkKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkKICAgICAgICBGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkgb2JqOwoKICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UpCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBpbnQzMkZpZWxkMV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiaW50MzJfZmllbGQiIGJlY2F1c2U6CiAgICAvLyAgICAgYm90aCByZXBlYXRlZCBmaWVsZCAiaW50MzJfZmllbGQiIGFuZCBzaW5ndWxhciBmaWVsZCAiaW50MzJfZmllbGRfbGlzdCIgZ2VuZXJhdGUgdGhlIG1ldGhvZCAiZ2V0SW50MzJGaWVsZExpc3QoKSIKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgaW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGludDMyRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRJbnQzMkZpZWxkMUxpc3QoKSB7CiAgICAgIHJldHVybiBpbnQzMkZpZWxkMV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBpbnQzMkZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGQxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnQzMkZpZWxkMV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBpbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMkZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRJbnQzMkZpZWxkMShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGludDMyRmllbGQxXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fRklFTERfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZW51bUZpZWxkMl87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtPiBlbnVtRmllbGQyX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0uVU5LTk9XTiA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvLyBBbiBhbHRlcm5hdGl2ZSBuYW1lIGlzIHVzZWQgZm9yIGZpZWxkICJlbnVtX2ZpZWxkIiBiZWNhdXNlOgogICAgLy8gICAgIGNhcGl0YWxpemVkIG5hbWUgb2YgZmllbGQgImVudW1fZmllbGQiIGNvbmZsaWN0cyB3aXRoIGZpZWxkICJFbnVtRmllbGQiCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW1GaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bT4gZ2V0RW51bUZpZWxkMkxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0+KGVudW1GaWVsZDJfLCBlbnVtRmllbGQyX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBlbnVtRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RW51bUZpZWxkMkNvdW50KCkgewogICAgICByZXR1cm4gZW51bUZpZWxkMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW1GaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gZ2V0RW51bUZpZWxkMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGVudW1GaWVsZDJfY29udmVydGVyXy5jb252ZXJ0KGVudW1GaWVsZDJfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCBzdHJpbmdGaWVsZDNfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvLyBBbiBhbHRlcm5hdGl2ZSBuYW1lIGlzIHVzZWQgZm9yIGZpZWxkICJzdHJpbmdfZmllbGQiIGJlY2F1c2U6CiAgICAvLyAgICAgY2FwaXRhbGl6ZWQgbmFtZSBvZiBmaWVsZCAic3RyaW5nX2ZpZWxkIiBjb25mbGljdHMgd2l0aCBmaWVsZCAiU3RyaW5nRmllbGQiCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHN0cmluZ0ZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRTdHJpbmdGaWVsZDNMaXN0KCkgewogICAgICByZXR1cm4gc3RyaW5nRmllbGQzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2Ygc3RyaW5nRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nRmllbGQzQ291bnQoKSB7CiAgICAgIHJldHVybiBzdHJpbmdGaWVsZDNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkMyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkM18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cmluZ0ZpZWxkM0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gc3RyaW5nRmllbGQzXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCWVRFU19GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gYnl0ZXNGaWVsZDRfID0KICAgICAgICBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgIC8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgImJ5dGVzX2ZpZWxkIiBiZWNhdXNlOgogICAgLy8gICAgIGNhcGl0YWxpemVkIG5hbWUgb2YgZmllbGQgImJ5dGVzX2ZpZWxkIiBjb25mbGljdHMgd2l0aCBmaWVsZCAiQnl0ZXNGaWVsZCIKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgYnl0ZXNfZmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGJ5dGVzRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZ2V0Qnl0ZXNGaWVsZDRMaXN0KCkgewogICAgICByZXR1cm4gYnl0ZXNGaWVsZDRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBieXRlc19maWVsZCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgYnl0ZXNGaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRCeXRlc0ZpZWxkNENvdW50KCkgewogICAgICByZXR1cm4gYnl0ZXNGaWVsZDRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgYnl0ZXNfZmllbGQgPSA0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Qnl0ZXNGaWVsZDQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBieXRlc0ZpZWxkNF8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+IG1lc3NhZ2VGaWVsZDVfOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAibWVzc2FnZV9maWVsZCIgYmVjYXVzZToKICAgIC8vICAgICBjYXBpdGFsaXplZCBuYW1lIG9mIGZpZWxkICJtZXNzYWdlX2ZpZWxkIiBjb25mbGljdHMgd2l0aCBmaWVsZCAiTWVzc2FnZUZpZWxkIgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPiBnZXRNZXNzYWdlRmllbGQ1TGlzdCgpIHsKICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZDVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0TWVzc2FnZUZpZWxkNU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQ1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWVzc2FnZUZpZWxkNUNvdW50KCkgewogICAgICByZXR1cm4gbWVzc2FnZUZpZWxkNV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldE1lc3NhZ2VGaWVsZDUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQ1Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZDVPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQ1Xy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX0ZJRUxEX0NPVU5UX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBpbnQgaW50MzJGaWVsZENvdW50MTFfID0gMDsKICAgIC8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgImludDMyX2ZpZWxkX2NvdW50IiBiZWNhdXNlOgogICAgLy8gICAgIGJvdGggcmVwZWF0ZWQgZmllbGQgIkludDMyRmllbGQiIGFuZCBzaW5ndWxhciBmaWVsZCAiaW50MzJfZmllbGRfY291bnQiIGdlbmVyYXRlIHRoZSBtZXRob2QgImdldEludDMyRmllbGRDb3VudCgpIgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnQzMl9maWVsZF9jb3VudCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50MzJGaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSW50MzJGaWVsZENvdW50MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50MzJfZmllbGRfY291bnQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMkZpZWxkQ291bnQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJGaWVsZENvdW50MTEoKSB7CiAgICAgIHJldHVybiBpbnQzMkZpZWxkQ291bnQxMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9GSUVMRF9DT1VOVF9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgaW50IGVudW1GaWVsZENvdW50MTJfID0gMDsKICAgIC8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgImVudW1fZmllbGRfY291bnQiIGJlY2F1c2U6CiAgICAvLyAgICAgYm90aCByZXBlYXRlZCBmaWVsZCAiRW51bUZpZWxkIiBhbmQgc2luZ3VsYXIgZmllbGQgImVudW1fZmllbGRfY291bnQiIGdlbmVyYXRlIHRoZSBtZXRob2QgImdldEVudW1GaWVsZENvdW50KCkiCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGRfY291bnQgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudW1GaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNFbnVtRmllbGRDb3VudDEyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGRfY291bnQgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGRDb3VudC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGdldEVudW1GaWVsZENvdW50MTIoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0uZm9yTnVtYmVyKGVudW1GaWVsZENvdW50MTJfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtLlVOS05PV04gOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX0ZJRUxEX0NPVU5UX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nRmllbGRDb3VudDEzXyA9ICIiOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAic3RyaW5nX2ZpZWxkX2NvdW50IiBiZWNhdXNlOgogICAgLy8gICAgIGJvdGggcmVwZWF0ZWQgZmllbGQgIlN0cmluZ0ZpZWxkIiBhbmQgc2luZ3VsYXIgZmllbGQgInN0cmluZ19maWVsZF9jb3VudCIgZ2VuZXJhdGUgdGhlIG1ldGhvZCAiZ2V0U3RyaW5nRmllbGRDb3VudCgpIgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkX2NvdW50ID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nRmllbGRDb3VudDEzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGRfY291bnQgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZENvdW50LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdGaWVsZENvdW50MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nRmllbGRDb3VudDEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHJpbmdGaWVsZENvdW50MTNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZF9jb3VudCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZENvdW50LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nRmllbGRDb3VudDEzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nRmllbGRDb3VudDEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyaW5nRmllbGRDb3VudDEzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJZVEVTX0ZJRUxEX0NPVU5UX0ZJRUxEX05VTUJFUiA9IDE0OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXNGaWVsZENvdW50MTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiYnl0ZXNfZmllbGRfY291bnQiIGJlY2F1c2U6CiAgICAvLyAgICAgYm90aCByZXBlYXRlZCBmaWVsZCAiQnl0ZXNGaWVsZCIgYW5kIHNpbmd1bGFyIGZpZWxkICJieXRlc19maWVsZF9jb3VudCIgZ2VuZXJhdGUgdGhlIG1ldGhvZCAiZ2V0Qnl0ZXNGaWVsZENvdW50KCkiCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX2ZpZWxkX2NvdW50ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBieXRlc0ZpZWxkQ291bnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCeXRlc0ZpZWxkQ291bnQxNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBieXRlc19maWVsZF9jb3VudCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzRmllbGRDb3VudC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRCeXRlc0ZpZWxkQ291bnQxNCgpIHsKICAgICAgcmV0dXJuIGJ5dGVzRmllbGRDb3VudDE0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0ZJRUxEX0NPVU5UX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlRmllbGRDb3VudDE1XzsKICAgIC8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgIm1lc3NhZ2VfZmllbGRfY291bnQiIGJlY2F1c2U6CiAgICAvLyAgICAgYm90aCByZXBlYXRlZCBmaWVsZCAiTWVzc2FnZUZpZWxkIiBhbmQgc2luZ3VsYXIgZmllbGQgIm1lc3NhZ2VfZmllbGRfY291bnQiIGdlbmVyYXRlIHRoZSBtZXRob2QgImdldE1lc3NhZ2VGaWVsZENvdW50KCkiCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZF9jb3VudCA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUZpZWxkQ291bnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlRmllbGRDb3VudDE1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZF9jb3VudCA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VGaWVsZENvdW50LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0TWVzc2FnZUZpZWxkQ291bnQxNSgpIHsKICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZENvdW50MTVfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VGaWVsZENvdW50MTVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGRfY291bnQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlciBnZXRNZXNzYWdlRmllbGRDb3VudDE1T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbWVzc2FnZUZpZWxkQ291bnQxNV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkQ291bnQxNV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJGSUVMRF9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgaW50MzJGaWVsZDIxXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvLyBBbiBhbHRlcm5hdGl2ZSBuYW1lIGlzIHVzZWQgZm9yIGZpZWxkICJJbnQzMkZpZWxkIiBiZWNhdXNlOgogICAgLy8gICAgIGJvdGggcmVwZWF0ZWQgZmllbGQgIkludDMyRmllbGQiIGFuZCBzaW5ndWxhciBmaWVsZCAiaW50MzJfZmllbGRfbGlzdCIgZ2VuZXJhdGUgdGhlIG1ldGhvZCAiZ2V0SW50MzJGaWVsZExpc3QoKSIKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgSW50MzJGaWVsZCA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGludDMyRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRJbnQzMkZpZWxkMjFMaXN0KCkgewogICAgICByZXR1cm4gaW50MzJGaWVsZDIxXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgSW50MzJGaWVsZCA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGludDMyRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJGaWVsZDIxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnQzMkZpZWxkMjFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgSW50MzJGaWVsZCA9IDIxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJGaWVsZDIxKGludCBpbmRleCkgewogICAgICByZXR1cm4gaW50MzJGaWVsZDIxXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1GSUVMRF9GSUVMRF9OVU1CRVIgPSAyMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZW51bUZpZWxkMjJfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bT4gZW51bUZpZWxkMjJfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bS5VTktOT1dOIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgIkVudW1GaWVsZCIgYmVjYXVzZToKICAgIC8vICAgICBib3RoIHJlcGVhdGVkIGZpZWxkICJFbnVtRmllbGQiIGFuZCBzaW5ndWxhciBmaWVsZCAiZW51bV9maWVsZF9jb3VudCIgZ2VuZXJhdGUgdGhlIG1ldGhvZCAiZ2V0RW51bUZpZWxkQ291bnQoKSIKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gRW51bUZpZWxkID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bUZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtPiBnZXRFbnVtRmllbGQyMkxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0+KGVudW1GaWVsZDIyXywgZW51bUZpZWxkMjJfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIEVudW1GaWVsZCA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGVudW1GaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRFbnVtRmllbGQyMkNvdW50KCkgewogICAgICByZXR1cm4gZW51bUZpZWxkMjJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gRW51bUZpZWxkID0gMjI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGdldEVudW1GaWVsZDIyKGludCBpbmRleCkgewogICAgICByZXR1cm4gZW51bUZpZWxkMjJfY29udmVydGVyXy5jb252ZXJ0KGVudW1GaWVsZDIyXy5nZXQoaW5kZXgpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdGSUVMRF9GSUVMRF9OVU1CRVIgPSAyMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3Qgc3RyaW5nRmllbGQyM18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgIlN0cmluZ0ZpZWxkIiBiZWNhdXNlOgogICAgLy8gICAgIGJvdGggcmVwZWF0ZWQgZmllbGQgIlN0cmluZ0ZpZWxkIiBhbmQgc2luZ3VsYXIgZmllbGQgInN0cmluZ19maWVsZF9jb3VudCIgZ2VuZXJhdGUgdGhlIG1ldGhvZCAiZ2V0U3RyaW5nRmllbGRDb3VudCgpIgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0U3RyaW5nRmllbGQyM0xpc3QoKSB7CiAgICAgIHJldHVybiBzdHJpbmdGaWVsZDIzXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2Ygc3RyaW5nRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nRmllbGQyM0NvdW50KCkgewogICAgICByZXR1cm4gc3RyaW5nRmllbGQyM18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nRmllbGQyMyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkMjNfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmdGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHJpbmdGaWVsZDIzQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBzdHJpbmdGaWVsZDIzXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCWVRFU0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gYnl0ZXNGaWVsZDI0XyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvLyBBbiBhbHRlcm5hdGl2ZSBuYW1lIGlzIHVzZWQgZm9yIGZpZWxkICJCeXRlc0ZpZWxkIiBiZWNhdXNlOgogICAgLy8gICAgIGJvdGggcmVwZWF0ZWQgZmllbGQgIkJ5dGVzRmllbGQiIGFuZCBzaW5ndWxhciBmaWVsZCAiYnl0ZXNfZmllbGRfY291bnQiIGdlbmVyYXRlIHRoZSBtZXRob2QgImdldEJ5dGVzRmllbGRDb3VudCgpIgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBCeXRlc0ZpZWxkID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgYnl0ZXNGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRCeXRlc0ZpZWxkMjRMaXN0KCkgewogICAgICByZXR1cm4gYnl0ZXNGaWVsZDI0XzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgQnl0ZXNGaWVsZCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGJ5dGVzRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0Qnl0ZXNGaWVsZDI0Q291bnQoKSB7CiAgICAgIHJldHVybiBieXRlc0ZpZWxkMjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgQnl0ZXNGaWVsZCA9IDI0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Qnl0ZXNGaWVsZDI0KGludCBpbmRleCkgewogICAgICByZXR1cm4gYnl0ZXNGaWVsZDI0Xy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VGSUVMRF9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gbWVzc2FnZUZpZWxkMjVfOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiTWVzc2FnZUZpZWxkIiBiZWNhdXNlOgogICAgLy8gICAgIGJvdGggcmVwZWF0ZWQgZmllbGQgIk1lc3NhZ2VGaWVsZCIgYW5kIHNpbmd1bGFyIGZpZWxkICJtZXNzYWdlX2ZpZWxkX2NvdW50IiBnZW5lcmF0ZSB0aGUgbWV0aG9kICJnZXRNZXNzYWdlRmllbGRDb3VudCgpIgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPiBnZXRNZXNzYWdlRmllbGQyNUxpc3QoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQyNV87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRNZXNzYWdlRmllbGQyNU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQyNV87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1lc3NhZ2VGaWVsZDI1Q291bnQoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQyNV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldE1lc3NhZ2VGaWVsZDI1KGludCBpbmRleCkgewogICAgICByZXR1cm4gbWVzc2FnZUZpZWxkMjVfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXIgZ2V0TWVzc2FnZUZpZWxkMjVPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGQyNV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9GSUVMRF9MSVNUX0ZJRUxEX05VTUJFUiA9IDMxOwogICAgcHJpdmF0ZSBpbnQgaW50MzJGaWVsZExpc3QzMV8gPSAwOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiaW50MzJfZmllbGRfbGlzdCIgYmVjYXVzZToKICAgIC8vICAgICBib3RoIHJlcGVhdGVkIGZpZWxkICJJbnQzMkZpZWxkIiBhbmQgc2luZ3VsYXIgZmllbGQgImludDMyX2ZpZWxkX2xpc3QiIGdlbmVyYXRlIHRoZSBtZXRob2QgImdldEludDMyRmllbGRMaXN0KCkiCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIGZpZWxkIGNvbmZsaWN0cyB3aXRoICJpbnQzMl9maWVsZCIgYXMgdGhleSBib3RoIGdlbmVyYXRlCiAgICAgKiB0aGUgbWV0aG9kIGdldEludDMyRmllbGRMaXN0KCkuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpbnQzMl9maWVsZF9saXN0ID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQzMkZpZWxkTGlzdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludDMyRmllbGRMaXN0MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgZmllbGQgY29uZmxpY3RzIHdpdGggImludDMyX2ZpZWxkIiBhcyB0aGV5IGJvdGggZ2VuZXJhdGUKICAgICAqIHRoZSBtZXRob2QgZ2V0SW50MzJGaWVsZExpc3QoKS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGludDMyX2ZpZWxkX2xpc3QgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMkZpZWxkTGlzdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMkZpZWxkTGlzdDMxKCkgewogICAgICByZXR1cm4gaW50MzJGaWVsZExpc3QzMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTkFNRV9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkTmFtZTMyXyA9ICIiOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiZmllbGRfbmFtZSIgYmVjYXVzZToKICAgIC8vICAgICBjYXBpdGFsaXplZCBuYW1lIG9mIGZpZWxkICJmaWVsZF9uYW1lIiBjb25mbGljdHMgd2l0aCBmaWVsZCAiZmllbGRfX25hbWUiCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBmaWVsZCBwYWlycyBoYXZlIHRoZSBzYW1lIEphdmEgY29udmVydGVkIG5hbWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9uYW1lID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE5hbWUzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZmllbGQgcGFpcnMgaGF2ZSB0aGUgc2FtZSBKYXZhIGNvbnZlcnRlZCBuYW1lCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfbmFtZSA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGROYW1lMzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGROYW1lMzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGZpZWxkTmFtZTMyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBmaWVsZCBwYWlycyBoYXZlIHRoZSBzYW1lIEphdmEgY29udmVydGVkIG5hbWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9uYW1lID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkTmFtZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkTmFtZTMyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGROYW1lMzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBmaWVsZE5hbWUzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9fTkFNRV9GSUVMRF9OVU1CRVIgPSAzMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkTmFtZTMzXyA9ICIiOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiZmllbGRfX25hbWUiIGJlY2F1c2U6CiAgICAvLyAgICAgY2FwaXRhbGl6ZWQgbmFtZSBvZiBmaWVsZCAiZmllbGRfbmFtZSIgY29uZmxpY3RzIHdpdGggZmllbGQgImZpZWxkX19uYW1lIgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8zCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfX25hbWUgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTmFtZTMzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9fbmFtZSA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGROYW1lMzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGROYW1lMzNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGZpZWxkTmFtZTMzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9fbmFtZSA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZE5hbWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZE5hbWUzM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkTmFtZTMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgZmllbGROYW1lMzNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgXzJDT05GTElDVF9GSUVMRF9OVU1CRVIgPSAzNDsKICAgIHByaXZhdGUgaW50IF8yQ29uZmxpY3QzNF8gPSAwOwogICAgLy8gQW4gYWx0ZXJuYXRpdmUgbmFtZSBpcyB1c2VkIGZvciBmaWVsZCAiXzJjb25mbGljdCIgYmVjYXVzZToKICAgIC8vICAgICBjYXBpdGFsaXplZCBuYW1lIG9mIGZpZWxkICJfMmNvbmZsaWN0IiBjb25mbGljdHMgd2l0aCBmaWVsZCAiX18yY29uZmxpY3QiCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8yY29uZmxpY3QgPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIDJjb25mbGljdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhczJDb25mbGljdDM0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOT19QUk9UTzMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8yY29uZmxpY3QgPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSAyY29uZmxpY3QuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0MkNvbmZsaWN0MzQoKSB7CiAgICAgIHJldHVybiBfMkNvbmZsaWN0MzRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9fMkNPTkZMSUNUX0ZJRUxEX05VTUJFUiA9IDM1OwogICAgcHJpdmF0ZSBpbnQgXzJDb25mbGljdDM1XyA9IDA7CiAgICAvLyBBbiBhbHRlcm5hdGl2ZSBuYW1lIGlzIHVzZWQgZm9yIGZpZWxkICJfXzJjb25mbGljdCIgYmVjYXVzZToKICAgIC8vICAgICBjYXBpdGFsaXplZCBuYW1lIG9mIGZpZWxkICJfMmNvbmZsaWN0IiBjb25mbGljdHMgd2l0aCBmaWVsZCAiX18yY29uZmxpY3QiCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF9fMmNvbmZsaWN0ID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAyY29uZmxpY3QgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXMyQ29uZmxpY3QzNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfXzJjb25mbGljdCA9IDM1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIDJjb25mbGljdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXQyQ29uZmxpY3QzNSgpIHsKICAgICAgcmV0dXJuIF8yQ29uZmxpY3QzNV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UNjRfRklFTERfRklFTERfTlVNQkVSID0gNDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBpbnQ2NEZpZWxkXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGludDY0RmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRJbnQ2NEZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIGludDY0RmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGludDY0RmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0SW50NjRGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50NjRGaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgaW50NjRGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEludDY0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBpbnQ2NEZpZWxkXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc0ludDMyRmllbGRMaXN0MzEoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcz4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnQzMkZpZWxkMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBpbnQzMkZpZWxkMV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1GaWVsZDJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyLCBlbnVtRmllbGQyXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RyaW5nRmllbGQzXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMywgc3RyaW5nRmllbGQzXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXNGaWVsZDRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoNCwgYnl0ZXNGaWVsZDRfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlRmllbGQ1Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNSwgbWVzc2FnZUZpZWxkNV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMSwgaW50MzJGaWVsZENvdW50MTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEyLCBlbnVtRmllbGRDb3VudDEyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMywgc3RyaW5nRmllbGRDb3VudDEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMTQsIGJ5dGVzRmllbGRDb3VudDE0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxNSwgZ2V0TWVzc2FnZUZpZWxkQ291bnQxNSgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludDMyRmllbGQyMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyMSwgaW50MzJGaWVsZDIxXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bUZpZWxkMjJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyMiwgZW51bUZpZWxkMjJfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJpbmdGaWVsZDIzXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjMsIHN0cmluZ0ZpZWxkMjNfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlc0ZpZWxkMjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMjQsIGJ5dGVzRmllbGQyNF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VGaWVsZDI1Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjUsIG1lc3NhZ2VGaWVsZDI1Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMxLCBpbnQzMkZpZWxkTGlzdDMxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzMiwgZmllbGROYW1lMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDMzLCBmaWVsZE5hbWUzM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDM0LCBfMkNvbmZsaWN0MzRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzNSwgXzJDb25mbGljdDM1Xyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnQ2NEZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDQxLCBpbnQ2NEZpZWxkXy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzA5MTIsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludDMyRmllbGQxXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGludDMyRmllbGQxXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldEludDMyRmllbGQxTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1GaWVsZDJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhlbnVtRmllbGQyXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGVudW1GaWVsZDJfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0cmluZ0ZpZWxkM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcoc3RyaW5nRmllbGQzXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFN0cmluZ0ZpZWxkM0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlc0ZpZWxkNF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemVOb1RhZyhieXRlc0ZpZWxkNF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRCeXRlc0ZpZWxkNExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlRmllbGQ1Xy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBtZXNzYWdlRmllbGQ1Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMTEsIGludDMyRmllbGRDb3VudDExXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEyLCBlbnVtRmllbGRDb3VudDEyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMywgc3RyaW5nRmllbGRDb3VudDEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxNCwgYnl0ZXNGaWVsZENvdW50MTRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUsIGdldE1lc3NhZ2VGaWVsZENvdW50MTUoKSk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnQzMkZpZWxkMjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoaW50MzJGaWVsZDIxXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEludDMyRmllbGQyMUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtRmllbGQyMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKGVudW1GaWVsZDIyXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGVudW1GaWVsZDIyXy5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJpbmdGaWVsZDIzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhzdHJpbmdGaWVsZDIzXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFN0cmluZ0ZpZWxkMjNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXNGaWVsZDI0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZU5vVGFnKGJ5dGVzRmllbGQyNF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRCeXRlc0ZpZWxkMjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZUZpZWxkMjVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI1LCBtZXNzYWdlRmllbGQyNV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMxLCBpbnQzMkZpZWxkTGlzdDMxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgzMiwgZmllbGROYW1lMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDMzLCBmaWVsZE5hbWUzM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMzQsIF8yQ29uZmxpY3QzNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMzUsIF8yQ29uZmxpY3QzNV8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50NjRGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhpbnQ2NEZpZWxkXy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRJbnQ2NEZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMpIG9iajsKCiAgICAgIGlmICghZ2V0SW50MzJGaWVsZDFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW50MzJGaWVsZDFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZW51bUZpZWxkMl8uZXF1YWxzKG90aGVyLmVudW1GaWVsZDJfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFN0cmluZ0ZpZWxkM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHJpbmdGaWVsZDNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0Qnl0ZXNGaWVsZDRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Qnl0ZXNGaWVsZDRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0TWVzc2FnZUZpZWxkNUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNZXNzYWdlRmllbGQ1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSW50MzJGaWVsZENvdW50MTEoKSAhPSBvdGhlci5oYXNJbnQzMkZpZWxkQ291bnQxMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbnQzMkZpZWxkQ291bnQxMSgpKSB7CiAgICAgICAgaWYgKGdldEludDMyRmllbGRDb3VudDExKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0SW50MzJGaWVsZENvdW50MTEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNFbnVtRmllbGRDb3VudDEyKCkgIT0gb3RoZXIuaGFzRW51bUZpZWxkQ291bnQxMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNFbnVtRmllbGRDb3VudDEyKCkpIHsKICAgICAgICBpZiAoZW51bUZpZWxkQ291bnQxMl8gIT0gb3RoZXIuZW51bUZpZWxkQ291bnQxMl8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nRmllbGRDb3VudDEzKCkgIT0gb3RoZXIuaGFzU3RyaW5nRmllbGRDb3VudDEzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cmluZ0ZpZWxkQ291bnQxMygpKSB7CiAgICAgICAgaWYgKCFnZXRTdHJpbmdGaWVsZENvdW50MTMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cmluZ0ZpZWxkQ291bnQxMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNCeXRlc0ZpZWxkQ291bnQxNCgpICE9IG90aGVyLmhhc0J5dGVzRmllbGRDb3VudDE0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0J5dGVzRmllbGRDb3VudDE0KCkpIHsKICAgICAgICBpZiAoIWdldEJ5dGVzRmllbGRDb3VudDE0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCeXRlc0ZpZWxkQ291bnQxNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlRmllbGRDb3VudDE1KCkgIT0gb3RoZXIuaGFzTWVzc2FnZUZpZWxkQ291bnQxNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNNZXNzYWdlRmllbGRDb3VudDE1KCkpIHsKICAgICAgICBpZiAoIWdldE1lc3NhZ2VGaWVsZENvdW50MTUoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE1lc3NhZ2VGaWVsZENvdW50MTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldEludDMyRmllbGQyMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRJbnQzMkZpZWxkMjFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZW51bUZpZWxkMjJfLmVxdWFscyhvdGhlci5lbnVtRmllbGQyMl8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0U3RyaW5nRmllbGQyM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHJpbmdGaWVsZDIzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEJ5dGVzRmllbGQyNExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCeXRlc0ZpZWxkMjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0TWVzc2FnZUZpZWxkMjVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TWVzc2FnZUZpZWxkMjVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbnQzMkZpZWxkTGlzdDMxKCkgIT0gb3RoZXIuaGFzSW50MzJGaWVsZExpc3QzMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbnQzMkZpZWxkTGlzdDMxKCkpIHsKICAgICAgICBpZiAoZ2V0SW50MzJGaWVsZExpc3QzMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludDMyRmllbGRMaXN0MzEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE5hbWUzMigpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkTmFtZTMyKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTmFtZTMyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE5hbWUzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE5hbWUzMygpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTMzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkTmFtZTMzKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTmFtZTMzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE5hbWUzMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXMyQ29uZmxpY3QzNCgpICE9IG90aGVyLmhhczJDb25mbGljdDM0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhczJDb25mbGljdDM0KCkpIHsKICAgICAgICBpZiAoZ2V0MkNvbmZsaWN0MzQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXQyQ29uZmxpY3QzNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhczJDb25mbGljdDM1KCkgIT0gb3RoZXIuaGFzMkNvbmZsaWN0MzUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzMkNvbmZsaWN0MzUoKSkgewogICAgICAgIGlmIChnZXQyQ29uZmxpY3QzNSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldDJDb25mbGljdDM1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldEludDY0RmllbGRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW50NjRGaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0SW50MzJGaWVsZDFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJbnQzMkZpZWxkMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRFbnVtRmllbGQyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBFTlVNX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBlbnVtRmllbGQyXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRTdHJpbmdGaWVsZDNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyaW5nRmllbGQzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEJ5dGVzRmllbGQ0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Qnl0ZXNGaWVsZDRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0TWVzc2FnZUZpZWxkNUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TWVzc2FnZUZpZWxkNUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNJbnQzMkZpZWxkQ291bnQxMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfRklFTERfQ09VTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDMyRmllbGRDb3VudDExKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0VudW1GaWVsZENvdW50MTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVOVU1fRklFTERfQ09VTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGVudW1GaWVsZENvdW50MTJfOwogICAgICB9CiAgICAgIGlmIChoYXNTdHJpbmdGaWVsZENvdW50MTMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9DT1VOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyaW5nRmllbGRDb3VudDEzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzQnl0ZXNGaWVsZENvdW50MTQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJZVEVTX0ZJRUxEX0NPVU5UX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCeXRlc0ZpZWxkQ291bnQxNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc01lc3NhZ2VGaWVsZENvdW50MTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1FU1NBR0VfRklFTERfQ09VTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2VGaWVsZENvdW50MTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRJbnQzMkZpZWxkMjFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDMyRmllbGQyMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRFbnVtRmllbGQyMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU5VTUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBlbnVtRmllbGQyMl8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0U3RyaW5nRmllbGQyM0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cmluZ0ZpZWxkMjNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0Qnl0ZXNGaWVsZDI0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCWVRFU0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCeXRlc0ZpZWxkMjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0TWVzc2FnZUZpZWxkMjVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1FU1NBR0VGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TWVzc2FnZUZpZWxkMjVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzSW50MzJGaWVsZExpc3QzMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfRklFTERfTElTVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50MzJGaWVsZExpc3QzMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE5hbWUzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTkFNRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGROYW1lMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE5hbWUzMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfX05BTUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTmFtZTMzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzMkNvbmZsaWN0MzQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIF8yQ09ORkxJQ1RfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldDJDb25mbGljdDM0KCk7CiAgICAgIH0KICAgICAgaWYgKGhhczJDb25mbGljdDM1KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBfXzJDT05GTElDVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0MkNvbmZsaWN0MzUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0SW50NjRGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UNjRfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDY0RmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkNUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkQ291bnQxNUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkMjVGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludDMyRmllbGQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGVudW1GaWVsZDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBzdHJpbmdGaWVsZDNfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJ5dGVzRmllbGQ0XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGlmIChtZXNzYWdlRmllbGQ1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZpZWxkNV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVfID0gbnVsbDsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50MzJGaWVsZENvdW50MTFfID0gMDsKICAgICAgICBlbnVtRmllbGRDb3VudDEyXyA9IDA7CiAgICAgICAgc3RyaW5nRmllbGRDb3VudDEzXyA9ICIiOwogICAgICAgIGJ5dGVzRmllbGRDb3VudDE0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1XyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkQ291bnQxNUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaW50MzJGaWVsZDIxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGVudW1GaWVsZDIyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgc3RyaW5nRmllbGQyM18gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYnl0ZXNGaWVsZDI0XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGlmIChtZXNzYWdlRmllbGQyNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfID0gbnVsbDsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludDMyRmllbGRMaXN0MzFfID0gMDsKICAgICAgICBmaWVsZE5hbWUzMl8gPSAiIjsKICAgICAgICBmaWVsZE5hbWUzM18gPSAiIjsKICAgICAgICBfMkNvbmZsaWN0MzRfID0gMDsKICAgICAgICBfMkNvbmZsaWN0MzVfID0gMDsKICAgICAgICBpbnQ2NEZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBlbnVtRmllbGQyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGVudW1GaWVsZDJfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmVudW1GaWVsZDJfID0gZW51bUZpZWxkMl87CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgICAgbWVzc2FnZUZpZWxkNV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChtZXNzYWdlRmllbGQ1Xyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5tZXNzYWdlRmllbGQ1XyA9IG1lc3NhZ2VGaWVsZDVfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQubWVzc2FnZUZpZWxkNV8gPSBtZXNzYWdlRmllbGQ1QnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICBlbnVtRmllbGQyMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChlbnVtRmllbGQyMl8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQuZW51bUZpZWxkMjJfID0gZW51bUZpZWxkMjJfOwogICAgICAgIGlmIChtZXNzYWdlRmllbGQyNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgICBtZXNzYWdlRmllbGQyNV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChtZXNzYWdlRmllbGQyNV8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQubWVzc2FnZUZpZWxkMjVfID0gbWVzc2FnZUZpZWxkMjVfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQubWVzc2FnZUZpZWxkMjVfID0gbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBpbnQzMkZpZWxkMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmludDMyRmllbGQxXyA9IGludDMyRmllbGQxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHN0cmluZ0ZpZWxkM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ0ZpZWxkM18gPSBzdHJpbmdGaWVsZDNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgYnl0ZXNGaWVsZDRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5ieXRlc0ZpZWxkNF8gPSBieXRlc0ZpZWxkNF87CiAgICAgICAgfQogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyRmllbGRDb3VudDExXyA9IGludDMyRmllbGRDb3VudDExXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5lbnVtRmllbGRDb3VudDEyXyA9IGVudW1GaWVsZENvdW50MTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ0ZpZWxkQ291bnQxM18gPSBzdHJpbmdGaWVsZENvdW50MTNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJ5dGVzRmllbGRDb3VudDE0XyA9IGJ5dGVzRmllbGRDb3VudDE0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tZXNzYWdlRmllbGRDb3VudDE1XyA9IG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtZXNzYWdlRmllbGRDb3VudDE1XwogICAgICAgICAgICAgIDogbWVzc2FnZUZpZWxkQ291bnQxNUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICBpbnQzMkZpZWxkMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMkZpZWxkMjFfID0gaW50MzJGaWVsZDIxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHN0cmluZ0ZpZWxkMjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdGaWVsZDIzXyA9IHN0cmluZ0ZpZWxkMjNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgYnl0ZXNGaWVsZDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuYnl0ZXNGaWVsZDI0XyA9IGJ5dGVzRmllbGQyNF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50MzJGaWVsZExpc3QzMV8gPSBpbnQzMkZpZWxkTGlzdDMxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE5hbWUzMl8gPSBmaWVsZE5hbWUzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGROYW1lMzNfID0gZmllbGROYW1lMzNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Ll8yQ29uZmxpY3QzNF8gPSBfMkNvbmZsaWN0MzRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Ll8yQ29uZmxpY3QzNV8gPSBfMkNvbmZsaWN0MzVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgaW50NjRGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmludDY0RmllbGRfID0gaW50NjRGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcywgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIuaW50MzJGaWVsZDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGludDMyRmllbGQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaW50MzJGaWVsZDFfID0gb3RoZXIuaW50MzJGaWVsZDFfOwogICAgICAgICAgICBpbnQzMkZpZWxkMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVJbnQzMkZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBpbnQzMkZpZWxkMV8uYWRkQWxsKG90aGVyLmludDMyRmllbGQxXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5lbnVtRmllbGQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChlbnVtRmllbGQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZW51bUZpZWxkMl8gPSBvdGhlci5lbnVtRmllbGQyXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRW51bUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICBlbnVtRmllbGQyXy5hZGRBbGwob3RoZXIuZW51bUZpZWxkMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuc3RyaW5nRmllbGQzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChzdHJpbmdGaWVsZDNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBzdHJpbmdGaWVsZDNfID0gb3RoZXIuc3RyaW5nRmllbGQzXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlU3RyaW5nRmllbGQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHN0cmluZ0ZpZWxkM18uYWRkQWxsKG90aGVyLnN0cmluZ0ZpZWxkM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuYnl0ZXNGaWVsZDRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGJ5dGVzRmllbGQ0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgYnl0ZXNGaWVsZDRfID0gb3RoZXIuYnl0ZXNGaWVsZDRfOwogICAgICAgICAgICBieXRlc0ZpZWxkNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVCeXRlc0ZpZWxkNElzTXV0YWJsZSgpOwogICAgICAgICAgICBieXRlc0ZpZWxkNF8uYWRkQWxsKG90aGVyLmJ5dGVzRmllbGQ0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLm1lc3NhZ2VGaWVsZDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAobWVzc2FnZUZpZWxkNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkNV8gPSBvdGhlci5tZXNzYWdlRmllbGQ1XzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkNUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIG1lc3NhZ2VGaWVsZDVfLmFkZEFsbChvdGhlci5tZXNzYWdlRmllbGQ1Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIubWVzc2FnZUZpZWxkNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChtZXNzYWdlRmllbGQ1QnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkNUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBtZXNzYWdlRmllbGQ1QnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIG1lc3NhZ2VGaWVsZDVfID0gb3RoZXIubWVzc2FnZUZpZWxkNV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlRmllbGQ1RmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5tZXNzYWdlRmllbGQ1Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ludDMyRmllbGRDb3VudDExKCkpIHsKICAgICAgICAgIHNldEludDMyRmllbGRDb3VudDExKG90aGVyLmdldEludDMyRmllbGRDb3VudDExKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRW51bUZpZWxkQ291bnQxMigpKSB7CiAgICAgICAgICBzZXRFbnVtRmllbGRDb3VudDEyKG90aGVyLmdldEVudW1GaWVsZENvdW50MTIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHJpbmdGaWVsZENvdW50MTMoKSkgewogICAgICAgICAgc3RyaW5nRmllbGRDb3VudDEzXyA9IG90aGVyLnN0cmluZ0ZpZWxkQ291bnQxM187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0J5dGVzRmllbGRDb3VudDE0KCkpIHsKICAgICAgICAgIHNldEJ5dGVzRmllbGRDb3VudDE0KG90aGVyLmdldEJ5dGVzRmllbGRDb3VudDE0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTWVzc2FnZUZpZWxkQ291bnQxNSgpKSB7CiAgICAgICAgICBtZXJnZU1lc3NhZ2VGaWVsZENvdW50MTUob3RoZXIuZ2V0TWVzc2FnZUZpZWxkQ291bnQxNSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5pbnQzMkZpZWxkMjFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGludDMyRmllbGQyMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGludDMyRmllbGQyMV8gPSBvdGhlci5pbnQzMkZpZWxkMjFfOwogICAgICAgICAgICBpbnQzMkZpZWxkMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlSW50MzJGaWVsZDIxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGludDMyRmllbGQyMV8uYWRkQWxsKG90aGVyLmludDMyRmllbGQyMV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZW51bUZpZWxkMjJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGVudW1GaWVsZDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZW51bUZpZWxkMjJfID0gb3RoZXIuZW51bUZpZWxkMjJfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVFbnVtRmllbGQyMklzTXV0YWJsZSgpOwogICAgICAgICAgICBlbnVtRmllbGQyMl8uYWRkQWxsKG90aGVyLmVudW1GaWVsZDIyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5zdHJpbmdGaWVsZDIzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChzdHJpbmdGaWVsZDIzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgc3RyaW5nRmllbGQyM18gPSBvdGhlci5zdHJpbmdGaWVsZDIzXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlU3RyaW5nRmllbGQyM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBzdHJpbmdGaWVsZDIzXy5hZGRBbGwob3RoZXIuc3RyaW5nRmllbGQyM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuYnl0ZXNGaWVsZDI0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChieXRlc0ZpZWxkMjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBieXRlc0ZpZWxkMjRfID0gb3RoZXIuYnl0ZXNGaWVsZDI0XzsKICAgICAgICAgICAgYnl0ZXNGaWVsZDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUJ5dGVzRmllbGQyNElzTXV0YWJsZSgpOwogICAgICAgICAgICBieXRlc0ZpZWxkMjRfLmFkZEFsbChvdGhlci5ieXRlc0ZpZWxkMjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLm1lc3NhZ2VGaWVsZDI1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBtZXNzYWdlRmllbGQyNV8gPSBvdGhlci5tZXNzYWdlRmllbGQyNV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZU1lc3NhZ2VGaWVsZDI1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkMjVfLmFkZEFsbChvdGhlci5tZXNzYWdlRmllbGQyNV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLm1lc3NhZ2VGaWVsZDI1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkMjVfID0gb3RoZXIubWVzc2FnZUZpZWxkMjVfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICAgICAgICBtZXNzYWdlRmllbGQyNUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2VGaWVsZDI1RmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIubWVzc2FnZUZpZWxkMjVfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzSW50MzJGaWVsZExpc3QzMSgpKSB7CiAgICAgICAgICBzZXRJbnQzMkZpZWxkTGlzdDMxKG90aGVyLmdldEludDMyRmllbGRMaXN0MzEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZE5hbWUzMigpKSB7CiAgICAgICAgICBmaWVsZE5hbWUzMl8gPSBvdGhlci5maWVsZE5hbWUzMl87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkTmFtZTMzKCkpIHsKICAgICAgICAgIGZpZWxkTmFtZTMzXyA9IG90aGVyLmZpZWxkTmFtZTMzXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzMkNvbmZsaWN0MzQoKSkgewogICAgICAgICAgc2V0MkNvbmZsaWN0MzQob3RoZXIuZ2V0MkNvbmZsaWN0MzQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXMyQ29uZmxpY3QzNSgpKSB7CiAgICAgICAgICBzZXQyQ29uZmxpY3QzNShvdGhlci5nZXQyQ29uZmxpY3QzNSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5pbnQ2NEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChpbnQ2NEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaW50NjRGaWVsZF8gPSBvdGhlci5pbnQ2NEZpZWxkXzsKICAgICAgICAgICAgaW50NjRGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVJbnQ2NEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGludDY0RmllbGRfLmFkZEFsbChvdGhlci5pbnQ2NEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzSW50MzJGaWVsZExpc3QzMSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVJbnQzMkZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgaW50MzJGaWVsZDFfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVJbnQzMkZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQzMkZpZWxkMV8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgyLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlRW51bUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBlbnVtRmllbGQyXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlRW51bUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGVudW1GaWVsZDJfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgc3RyaW5nRmllbGQzXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHYgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUJ5dGVzRmllbGQ0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBieXRlc0ZpZWxkNF8uYWRkKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZU1lc3NhZ2VGaWVsZDVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkNV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkNUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDg4OiB7CiAgICAgICAgICAgICAgICBpbnQzMkZpZWxkQ291bnQxMV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OAogICAgICAgICAgICAgIGNhc2UgOTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVudW1GaWVsZENvdW50MTJfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTYKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgc3RyaW5nRmllbGRDb3VudDEzXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNgogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBieXRlc0ZpZWxkQ291bnQxNF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkQ291bnQxNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyCiAgICAgICAgICAgICAgY2FzZSAxNjg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVJbnQzMkZpZWxkMjFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGludDMyRmllbGQyMV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2OAogICAgICAgICAgICAgIGNhc2UgMTcwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUludDMyRmllbGQyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQzMkZpZWxkMjFfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTcwCiAgICAgICAgICAgICAgY2FzZSAxNzY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgyMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUVudW1GaWVsZDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIGVudW1GaWVsZDIyXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMjIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlRW51bUZpZWxkMjJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBlbnVtRmllbGQyMl8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzgKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVTdHJpbmdGaWVsZDIzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBzdHJpbmdGaWVsZDIzXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4NgogICAgICAgICAgICAgIGNhc2UgMTk0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlQnl0ZXNGaWVsZDI0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBieXRlc0ZpZWxkMjRfLmFkZCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQyNUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBtZXNzYWdlRmllbGQyNV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMgogICAgICAgICAgICAgIGNhc2UgMjQ4OiB7CiAgICAgICAgICAgICAgICBpbnQzMkZpZWxkTGlzdDMxXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0OAogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBmaWVsZE5hbWUzMl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBjYXNlIDI2NjogewogICAgICAgICAgICAgICAgZmllbGROYW1lMzNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY2CiAgICAgICAgICAgICAgY2FzZSAyNzI6IHsKICAgICAgICAgICAgICAgIF8yQ29uZmxpY3QzNF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzIKICAgICAgICAgICAgICBjYXNlIDI4MDogewogICAgICAgICAgICAgICAgXzJDb25mbGljdDM1XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MAogICAgICAgICAgICAgIGNhc2UgMzI4OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGludDY0RmllbGRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzI4CiAgICAgICAgICAgICAgY2FzZSAzMzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlSW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQ2NEZpZWxkXy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgaW50MzJGaWVsZDFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVJbnQzMkZpZWxkMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWludDMyRmllbGQxXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgaW50MzJGaWVsZDFfID0gbWFrZU11dGFibGVDb3B5KGludDMyRmllbGQxXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgaW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgaW50MzJGaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEludDMyRmllbGQxTGlzdCgpIHsKICAgICAgICBpbnQzMkZpZWxkMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBpbnQzMkZpZWxkMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGludDMyRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGQxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMkZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJGaWVsZDEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGQxXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBpbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW50MzJGaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEludDMyRmllbGQxKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlSW50MzJGaWVsZDFJc011dGFibGUoKTsKICAgICAgICBpbnQzMkZpZWxkMV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBpbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludDMyRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRJbnQzMkZpZWxkMShpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlSW50MzJGaWVsZDFJc011dGFibGUoKTsKICAgICAgICBpbnQzMkZpZWxkMV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGludDMyRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxJbnQzMkZpZWxkMSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUludDMyRmllbGQxSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGludDMyRmllbGQxXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBpbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyRmllbGQxKCkgewogICAgICAgIGludDMyRmllbGQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZW51bUZpZWxkMl8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUVudW1GaWVsZDJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgZW51bUZpZWxkMl8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4oZW51bUZpZWxkMl8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gZW51bV9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtPiBnZXRFbnVtRmllbGQyTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0+KGVudW1GaWVsZDJfLCBlbnVtRmllbGQyX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGVudW1GaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bUZpZWxkMkNvdW50KCkgewogICAgICAgIHJldHVybiBlbnVtRmllbGQyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW1GaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGdldEVudW1GaWVsZDIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGVudW1GaWVsZDJfY29udmVydGVyXy5jb252ZXJ0KGVudW1GaWVsZDJfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRFbnVtRmllbGQyKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUVudW1GaWVsZDJJc011dGFibGUoKTsKICAgICAgICBlbnVtRmllbGQyXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gZW51bV9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW1GaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEVudW1GaWVsZDIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVFbnVtRmllbGQySXNNdXRhYmxlKCk7CiAgICAgICAgZW51bUZpZWxkMl8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gZW51bV9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxFbnVtRmllbGQyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUVudW1GaWVsZDJJc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgZW51bUZpZWxkMl8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtRmllbGQyKCkgewogICAgICAgIGVudW1GaWVsZDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3Qgc3RyaW5nRmllbGQzXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVTdHJpbmdGaWVsZDNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFzdHJpbmdGaWVsZDNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdGaWVsZDNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChzdHJpbmdGaWVsZDNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRTdHJpbmdGaWVsZDNMaXN0KCkgewogICAgICAgIHN0cmluZ0ZpZWxkM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBzdHJpbmdGaWVsZDNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRTdHJpbmdGaWVsZDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGQzXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkMyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGQzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFN0cmluZ0ZpZWxkM0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBzdHJpbmdGaWVsZDNfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHJpbmdGaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZ0ZpZWxkMygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGQzSXNNdXRhYmxlKCk7CiAgICAgICAgc3RyaW5nRmllbGQzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHJpbmdGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN0cmluZ0ZpZWxkMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgIHN0cmluZ0ZpZWxkM18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgc3RyaW5nRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxTdHJpbmdGaWVsZDMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGQzSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHN0cmluZ0ZpZWxkM18pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ0ZpZWxkMygpIHsKICAgICAgICBzdHJpbmdGaWVsZDNfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHN0cmluZ0ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkU3RyaW5nRmllbGQzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgIHN0cmluZ0ZpZWxkM18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBieXRlc0ZpZWxkNF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUJ5dGVzRmllbGQ0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghYnl0ZXNGaWVsZDRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBieXRlc0ZpZWxkNF8gPSBtYWtlTXV0YWJsZUNvcHkoYnl0ZXNGaWVsZDRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBieXRlc19maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBieXRlc0ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldEJ5dGVzRmllbGQ0TGlzdCgpIHsKICAgICAgICBieXRlc0ZpZWxkNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBieXRlc0ZpZWxkNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGJ5dGVzX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGJ5dGVzRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEJ5dGVzRmllbGQ0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGJ5dGVzRmllbGQ0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGJ5dGVzX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlc0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Qnl0ZXNGaWVsZDQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGJ5dGVzRmllbGQ0Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBieXRlc19maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXNGaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJ5dGVzRmllbGQ0KAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUJ5dGVzRmllbGQ0SXNNdXRhYmxlKCk7CiAgICAgICAgYnl0ZXNGaWVsZDRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgYnl0ZXNfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlc0ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQnl0ZXNGaWVsZDQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVCeXRlc0ZpZWxkNElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGQ0Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgYnl0ZXNfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgYnl0ZXNGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEJ5dGVzRmllbGQ0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUJ5dGVzRmllbGQ0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGJ5dGVzRmllbGQ0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBieXRlc19maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJ5dGVzRmllbGQ0KCkgewogICAgICAgIGJ5dGVzRmllbGQ0XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gbWVzc2FnZUZpZWxkNV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZU1lc3NhZ2VGaWVsZDVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgbWVzc2FnZUZpZWxkNV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4obWVzc2FnZUZpZWxkNV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyPiBtZXNzYWdlRmllbGQ1QnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+IGdldE1lc3NhZ2VGaWVsZDVMaXN0KCkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGQ1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG1lc3NhZ2VGaWVsZDVfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldE1lc3NhZ2VGaWVsZDVDb3VudCgpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGQ1Xy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGQ1QnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldE1lc3NhZ2VGaWVsZDUoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkNV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZUZpZWxkNSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkNV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkNUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZUZpZWxkNSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZU1lc3NhZ2VGaWVsZDVJc011dGFibGUoKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE1lc3NhZ2VGaWVsZDUoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkNV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGQ1QnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE1lc3NhZ2VGaWVsZDUoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZU1lc3NhZ2VGaWVsZDVJc011dGFibGUoKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE1lc3NhZ2VGaWVsZDUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGQ1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkNV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGQ1QnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE1lc3NhZ2VGaWVsZDUoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQ1SXNNdXRhYmxlKCk7CiAgICAgICAgICBtZXNzYWdlRmllbGQ1Xy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGQ1QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxNZXNzYWdlRmllbGQ1KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQ1SXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCBtZXNzYWdlRmllbGQ1Xyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkNUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWVzc2FnZUZpZWxkNSgpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNZXNzYWdlRmllbGQ1KGludCBpbmRleCkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGQ1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkNV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGQ1QnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgZ2V0TWVzc2FnZUZpZWxkNUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZUZpZWxkNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlciBnZXRNZXNzYWdlRmllbGQ1T3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkNV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkNUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRNZXNzYWdlRmllbGQ1T3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGQ1QnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG1lc3NhZ2VGaWVsZDVfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgYWRkTWVzc2FnZUZpZWxkNUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VGaWVsZDVGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgYWRkTWVzc2FnZUZpZWxkNUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZUZpZWxkNUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldE1lc3NhZ2VGaWVsZDVCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZUZpZWxkNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkNUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDVCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkNV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZUZpZWxkNV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkNUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBpbnQzMkZpZWxkQ291bnQxMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50MzJfZmllbGRfY291bnQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50MzJGaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50MzJGaWVsZENvdW50MTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnQzMl9maWVsZF9jb3VudCA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZENvdW50LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGRDb3VudDExKCkgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkQ291bnQxMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludDMyX2ZpZWxkX2NvdW50ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludDMyRmllbGRDb3VudCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEludDMyRmllbGRDb3VudDExKGludCB2YWx1ZSkgewoKICAgICAgICBpbnQzMkZpZWxkQ291bnQxMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludDMyX2ZpZWxkX2NvdW50ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyRmllbGRDb3VudDExKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnQzMkZpZWxkQ291bnQxMV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBlbnVtRmllbGRDb3VudDEyXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkX2NvdW50ID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudW1GaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRW51bUZpZWxkQ291bnQxMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGVudW1fZmllbGRfY291bnQgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW1GaWVsZENvdW50LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIGdldEVudW1GaWVsZENvdW50MTIoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bS5mb3JOdW1iZXIoZW51bUZpZWxkQ291bnQxMl8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bS5VTktOT1dOIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkX2NvdW50ID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW1GaWVsZENvdW50IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RW51bUZpZWxkQ291bnQxMihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBlbnVtRmllbGRDb3VudDEyXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBlbnVtX2ZpZWxkX2NvdW50ID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVudW1GaWVsZENvdW50MTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGVudW1GaWVsZENvdW50MTJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cmluZ0ZpZWxkQ291bnQxM18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGRfY291bnQgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nRmllbGRDb3VudCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdGaWVsZENvdW50MTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkX2NvdW50ID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZENvdW50LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nRmllbGRDb3VudDEzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nRmllbGRDb3VudDEzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cmluZ0ZpZWxkQ291bnQxM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZF9jb3VudCA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ0ZpZWxkQ291bnQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdGaWVsZENvdW50MTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ0ZpZWxkQ291bnQxM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cmluZ0ZpZWxkQ291bnQxM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkX2NvdW50ID0gMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ0ZpZWxkQ291bnQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdGaWVsZENvdW50MTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHJpbmdGaWVsZENvdW50MTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkX2NvdW50ID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ0ZpZWxkQ291bnQxMygpIHsKICAgICAgICBzdHJpbmdGaWVsZENvdW50MTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyaW5nRmllbGRDb3VudDEzKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkX2NvdW50ID0gMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZENvdW50IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGRDb3VudDEzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cmluZ0ZpZWxkQ291bnQxM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzRmllbGRDb3VudDE0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX2ZpZWxkX2NvdW50ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJ5dGVzRmllbGRDb3VudCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0J5dGVzRmllbGRDb3VudDE0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgYnl0ZXNfZmllbGRfY291bnQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzRmllbGRDb3VudC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRCeXRlc0ZpZWxkQ291bnQxNCgpIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZENvdW50MTRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBieXRlc19maWVsZF9jb3VudCA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlc0ZpZWxkQ291bnQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCeXRlc0ZpZWxkQ291bnQxNChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGJ5dGVzRmllbGRDb3VudDE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgYnl0ZXNfZmllbGRfY291bnQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQnl0ZXNGaWVsZENvdW50MTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGJ5dGVzRmllbGRDb3VudDE0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEJ5dGVzRmllbGRDb3VudDE0KCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZUZpZWxkQ291bnQxNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlcj4gbWVzc2FnZUZpZWxkQ291bnQxNUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VGaWVsZENvdW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VGaWVsZENvdW50MTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGRfY291bnQgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VGaWVsZENvdW50LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIGdldE1lc3NhZ2VGaWVsZENvdW50MTUoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkQ291bnQxNV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkQ291bnQxNV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZUZpZWxkQ291bnQxNShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1XyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZUZpZWxkQ291bnQxNSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1XyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VNZXNzYWdlRmllbGRDb3VudDE1KGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZUZpZWxkQ291bnQxNV8gIT0gbnVsbCAmJgogICAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1XyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNZXNzYWdlRmllbGRDb3VudDE1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1XyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRDb3VudDE1QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkQ291bnQxNUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgbWVzc2FnZV9maWVsZF9jb3VudCA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyIGdldE1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZUZpZWxkQ291bnQxNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBtZXNzYWdlX2ZpZWxkX2NvdW50ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZENvdW50MTVPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkQ291bnQxNUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZENvdW50MTVfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkQ291bnQxNV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG1lc3NhZ2VfZmllbGRfY291bnQgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkQ291bnQxNUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkQ291bnQxNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2VGaWVsZENvdW50MTUoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZENvdW50MTVfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZENvdW50MTVCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgaW50MzJGaWVsZDIxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlSW50MzJGaWVsZDIxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghaW50MzJGaWVsZDIxXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgaW50MzJGaWVsZDIxXyA9IG1ha2VNdXRhYmxlQ29weShpbnQzMkZpZWxkMjFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGludDMyRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRJbnQzMkZpZWxkMjFMaXN0KCkgewogICAgICAgIGludDMyRmllbGQyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBpbnQzMkZpZWxkMjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGludDMyRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGQyMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkMjFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBJbnQzMkZpZWxkID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGQyMShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gaW50MzJGaWVsZDIxXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnQzMkZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50MzJGaWVsZDIxKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlSW50MzJGaWVsZDIxSXNNdXRhYmxlKCk7CiAgICAgICAgaW50MzJGaWVsZDIxXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgSW50MzJGaWVsZCA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnQzMkZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkSW50MzJGaWVsZDIxKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVJbnQzMkZpZWxkMjFJc011dGFibGUoKTsKICAgICAgICBpbnQzMkZpZWxkMjFfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGludDMyRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxJbnQzMkZpZWxkMjEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVJbnQzMkZpZWxkMjFJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgaW50MzJGaWVsZDIxXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIEludDMyRmllbGQgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJGaWVsZDIxKCkgewogICAgICAgIGludDMyRmllbGQyMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGVudW1GaWVsZDIyXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRW51bUZpZWxkMjJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgZW51bUZpZWxkMjJfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KGVudW1GaWVsZDIyXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIEVudW1GaWVsZCA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bUZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bT4gZ2V0RW51bUZpZWxkMjJMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bT4oZW51bUZpZWxkMjJfLCBlbnVtRmllbGQyMl9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBFbnVtRmllbGQgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGVudW1GaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bUZpZWxkMjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZW51bUZpZWxkMjJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBFbnVtRmllbGQgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBnZXRFbnVtRmllbGQyMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZW51bUZpZWxkMjJfY29udmVydGVyXy5jb252ZXJ0KGVudW1GaWVsZDIyXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBFbnVtRmllbGQgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRFbnVtRmllbGQyMigKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVFbnVtRmllbGQyMklzTXV0YWJsZSgpOwogICAgICAgIGVudW1GaWVsZDIyXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSBFbnVtRmllbGQgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bUZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRW51bUZpZWxkMjIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVFbnVtRmllbGQyMklzTXV0YWJsZSgpOwogICAgICAgIGVudW1GaWVsZDIyXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIEVudW1GaWVsZCA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bUZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRW51bUZpZWxkMjIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRW51bUZpZWxkMjJJc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgZW51bUZpZWxkMjJfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLlRlc3RFbnVtIEVudW1GaWVsZCA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtRmllbGQyMigpIHsKICAgICAgICBlbnVtRmllbGQyMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCBzdHJpbmdGaWVsZDIzXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVTdHJpbmdGaWVsZDIzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghc3RyaW5nRmllbGQyM18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ0ZpZWxkMjNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChzdHJpbmdGaWVsZDIzXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRTdHJpbmdGaWVsZDIzTGlzdCgpIHsKICAgICAgICBzdHJpbmdGaWVsZDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkMjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2Ygc3RyaW5nRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ0ZpZWxkMjNDb3VudCgpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGQyM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkMjMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkMjNfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmdGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdGaWVsZDIzQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkMjNfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ0ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGQyMygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGQyM0lzTXV0YWJsZSgpOwogICAgICAgIHN0cmluZ0ZpZWxkMjNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyaW5nRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRTdHJpbmdGaWVsZDIzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGQyM0lzTXV0YWJsZSgpOwogICAgICAgIHN0cmluZ0ZpZWxkMjNfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBTdHJpbmdGaWVsZCA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgc3RyaW5nRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxTdHJpbmdGaWVsZDIzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkMjNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgc3RyaW5nRmllbGQyM18pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nRmllbGQyMygpIHsKICAgICAgICBzdHJpbmdGaWVsZDIzXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHN0cmluZ0ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkU3RyaW5nRmllbGQyM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVTdHJpbmdGaWVsZDIzSXNNdXRhYmxlKCk7CiAgICAgICAgc3RyaW5nRmllbGQyM18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBieXRlc0ZpZWxkMjRfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVCeXRlc0ZpZWxkMjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFieXRlc0ZpZWxkMjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBieXRlc0ZpZWxkMjRfID0gbWFrZU11dGFibGVDb3B5KGJ5dGVzRmllbGQyNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgQnl0ZXNGaWVsZCA9IDI0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgYnl0ZXNGaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRCeXRlc0ZpZWxkMjRMaXN0KCkgewogICAgICAgIGJ5dGVzRmllbGQyNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBieXRlc0ZpZWxkMjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIEJ5dGVzRmllbGQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGJ5dGVzRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEJ5dGVzRmllbGQyNENvdW50KCkgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkMjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBCeXRlc0ZpZWxkID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEJ5dGVzRmllbGQyNChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZDI0Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIEJ5dGVzRmllbGQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlc0ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Qnl0ZXNGaWVsZDI0KAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUJ5dGVzRmllbGQyNElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGQyNF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIEJ5dGVzRmllbGQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXNGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEJ5dGVzRmllbGQyNChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUJ5dGVzRmllbGQyNElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGQyNF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgQnl0ZXNGaWVsZCA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgYnl0ZXNGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEJ5dGVzRmllbGQyNCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVCeXRlc0ZpZWxkMjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgYnl0ZXNGaWVsZDI0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIEJ5dGVzRmllbGQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQnl0ZXNGaWVsZDI0KCkgewogICAgICAgIGJ5dGVzRmllbGQyNF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+IG1lc3NhZ2VGaWVsZDI1XyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlTWVzc2FnZUZpZWxkMjVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+KG1lc3NhZ2VGaWVsZDI1Xyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXI+IG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gZ2V0TWVzc2FnZUZpZWxkMjVMaXN0KCkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGQyNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChtZXNzYWdlRmllbGQyNV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWVzc2FnZUZpZWxkMjVDb3VudCgpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkMjVfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgZ2V0TWVzc2FnZUZpZWxkMjUoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZDI1Xy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlRmllbGQyNSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZU1lc3NhZ2VGaWVsZDI1SXNNdXRhYmxlKCk7CiAgICAgICAgICBtZXNzYWdlRmllbGQyNV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZUZpZWxkMjUoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkMjVJc011dGFibGUoKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1Xy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGQyNUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRNZXNzYWdlRmllbGQyNShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGQyNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkMjVJc011dGFibGUoKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1Xy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkTWVzc2FnZUZpZWxkMjUoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQyNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE1lc3NhZ2VGaWVsZDI1KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQyNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRNZXNzYWdlRmllbGQyNSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQyNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbE1lc3NhZ2VGaWVsZDI1KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlTWVzc2FnZUZpZWxkMjVJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIG1lc3NhZ2VGaWVsZDI1Xyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWVzc2FnZUZpZWxkMjUoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNZXNzYWdlRmllbGQyNShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVNZXNzYWdlRmllbGQyNUlzTXV0YWJsZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkMjVfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyIGdldE1lc3NhZ2VGaWVsZDI1QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRNZXNzYWdlRmllbGQyNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZDI1T3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZDI1Xy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGQyNUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldE1lc3NhZ2VGaWVsZDI1T3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkMjVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkMjVCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobWVzc2FnZUZpZWxkMjVfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBNZXNzYWdlRmllbGQgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciBhZGRNZXNzYWdlRmllbGQyNUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VGaWVsZDI1RmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIgYWRkTWVzc2FnZUZpZWxkMjVCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VGaWVsZDI1RmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRNZXNzYWdlRmllbGQyNUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRNZXNzYWdlRmllbGQyNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkMjVGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZDI1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZpZWxkMjVCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgbWVzc2FnZUZpZWxkMjVfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZDI1XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtZXNzYWdlRmllbGQyNUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBpbnQzMkZpZWxkTGlzdDMxXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGlzIGZpZWxkIGNvbmZsaWN0cyB3aXRoICJpbnQzMl9maWVsZCIgYXMgdGhleSBib3RoIGdlbmVyYXRlCiAgICAgICAqIHRoZSBtZXRob2QgZ2V0SW50MzJGaWVsZExpc3QoKS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGludDMyX2ZpZWxkX2xpc3QgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50MzJGaWVsZExpc3QgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnQzMkZpZWxkTGlzdDMxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhpcyBmaWVsZCBjb25mbGljdHMgd2l0aCAiaW50MzJfZmllbGQiIGFzIHRoZXkgYm90aCBnZW5lcmF0ZQogICAgICAgKiB0aGUgbWV0aG9kIGdldEludDMyRmllbGRMaXN0KCkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpbnQzMl9maWVsZF9saXN0ID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMkZpZWxkTGlzdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMkZpZWxkTGlzdDMxKCkgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkTGlzdDMxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhpcyBmaWVsZCBjb25mbGljdHMgd2l0aCAiaW50MzJfZmllbGQiIGFzIHRoZXkgYm90aCBnZW5lcmF0ZQogICAgICAgKiB0aGUgbWV0aG9kIGdldEludDMyRmllbGRMaXN0KCkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpbnQzMl9maWVsZF9saXN0ID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludDMyRmllbGRMaXN0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50MzJGaWVsZExpc3QzMShpbnQgdmFsdWUpIHsKCiAgICAgICAgaW50MzJGaWVsZExpc3QzMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoaXMgZmllbGQgY29uZmxpY3RzIHdpdGggImludDMyX2ZpZWxkIiBhcyB0aGV5IGJvdGggZ2VuZXJhdGUKICAgICAgICogdGhlIG1ldGhvZCBnZXRJbnQzMkZpZWxkTGlzdCgpLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgaW50MzJfZmllbGRfbGlzdCA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMkZpZWxkTGlzdDMxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnQzMkZpZWxkTGlzdDMxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZE5hbWUzMl8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGZpZWxkIHBhaXJzIGhhdmUgdGhlIHNhbWUgSmF2YSBjb252ZXJ0ZWQgbmFtZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX25hbWUgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTmFtZTMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgZmllbGQgcGFpcnMgaGF2ZSB0aGUgc2FtZSBKYXZhIGNvbnZlcnRlZCBuYW1lCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfbmFtZSA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGROYW1lLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGROYW1lMzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZE5hbWUzMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBmaWVsZE5hbWUzMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgZmllbGQgcGFpcnMgaGF2ZSB0aGUgc2FtZSBKYXZhIGNvbnZlcnRlZCBuYW1lCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfbmFtZSA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkTmFtZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZpZWxkTmFtZTMyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZE5hbWUzMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGZpZWxkTmFtZTMyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGZpZWxkIHBhaXJzIGhhdmUgdGhlIHNhbWUgSmF2YSBjb252ZXJ0ZWQgbmFtZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX25hbWUgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGROYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGROYW1lMzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZE5hbWUzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGZpZWxkIHBhaXJzIGhhdmUgdGhlIHNhbWUgSmF2YSBjb252ZXJ0ZWQgbmFtZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX25hbWUgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGROYW1lMzIoKSB7CiAgICAgICAgZmllbGROYW1lMzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RmllbGROYW1lMzIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGZpZWxkIHBhaXJzIGhhdmUgdGhlIHNhbWUgSmF2YSBjb252ZXJ0ZWQgbmFtZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX25hbWUgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGZpZWxkTmFtZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTmFtZTMyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZpZWxkTmFtZTMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkTmFtZTMzXyA9ICIiOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfX25hbWUgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTmFtZTMzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfX25hbWUgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTmFtZTMzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGROYW1lMzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZmllbGROYW1lMzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX19uYW1lID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGROYW1lLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGROYW1lMzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkTmFtZTMzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgZmllbGROYW1lMzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8zCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfX25hbWUgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGROYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGROYW1lMzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZE5hbWUzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX19uYW1lID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTmFtZTMzKCkgewogICAgICAgIGZpZWxkTmFtZTMzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEZpZWxkTmFtZTMzKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9fbmFtZSA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZmllbGROYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGROYW1lMzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGROYW1lMzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBfMkNvbmZsaWN0MzRfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzJjb25mbGljdCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAyY29uZmxpY3QgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXMyQ29uZmxpY3QzNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzJjb25mbGljdCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgMmNvbmZsaWN0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldDJDb25mbGljdDM0KCkgewogICAgICAgIHJldHVybiBfMkNvbmZsaWN0MzRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOT19QUk9UTzMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8yY29uZmxpY3QgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgMmNvbmZsaWN0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0MkNvbmZsaWN0MzQoaW50IHZhbHVlKSB7CgogICAgICAgIF8yQ29uZmxpY3QzNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzJjb25mbGljdCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIyQ29uZmxpY3QzNCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgXzJDb25mbGljdDM0XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IF8yQ29uZmxpY3QzNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgX18yY29uZmxpY3QgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgMmNvbmZsaWN0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzMkNvbmZsaWN0MzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfXzJjb25mbGljdCA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgMmNvbmZsaWN0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldDJDb25mbGljdDM1KCkgewogICAgICAgIHJldHVybiBfMkNvbmZsaWN0MzVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfXzJjb25mbGljdCA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSAyY29uZmxpY3QgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXQyQ29uZmxpY3QzNShpbnQgdmFsdWUpIHsKCiAgICAgICAgXzJDb25mbGljdDM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgX18yY29uZmxpY3QgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyMkNvbmZsaWN0MzUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIF8yQ29uZmxpY3QzNV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgaW50NjRGaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVJbnQ2NEZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghaW50NjRGaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGludDY0RmllbGRfID0gbWFrZU11dGFibGVDb3B5KGludDY0RmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgaW50NjRGaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEludDY0RmllbGRMaXN0KCkgewogICAgICAgIGludDY0RmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gaW50NjRGaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGludDY0X2ZpZWxkID0gNDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBpbnQ2NEZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRJbnQ2NEZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludDY0RmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgaW50NjRfZmllbGQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBpbnQ2NEZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEludDY0RmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGludDY0RmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludDY0RmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQ2NEZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBpbnQ2NEZpZWxkXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBpbnQ2NF9maWVsZCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnQ2NEZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkSW50NjRGaWVsZChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBpbnQ2NEZpZWxkXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGludDY0X2ZpZWxkID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBpbnQ2NEZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsSW50NjRGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgaW50NjRGaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgaW50NjRfZmllbGQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50NjRGaWVsZCgpIHsKICAgICAgICBpbnQ2NEZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdENvbmZsaWN0aW5nRmllbGROYW1lcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQ2NF9GSUVMRF9DT1VOVF9GSUVMRF9OVU1CRVIgPSAxMDAxOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2UgZG9uJ3QgZ2VuZXJhdGUgYWNjZXNzb3JzIGZvciBleHRlbnNpb25zIHNvIHRoZSBmb2xsb3dpbmcgZXh0ZW5zaW9uCiAgICAgKiBmaWVsZHMgZG9uJ3QgY29uZmxpY3Qgd2l0aCB0aGUgcmVwZWF0ZWQgZmllbGQgImludDY0X2ZpZWxkIi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPmV4dGVuZCAuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW1lcyB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLAogICAgICAgIGphdmEubGFuZy5Mb25nPiBpbnQ2NEZpZWxkQ291bnQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDY0X0ZJRUxEX0xJU1RfRklFTERfTlVNQkVSID0gMTAwMjsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+ZXh0ZW5kIC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMsCiAgICAgICAgamF2YS5sYW5nLkxvbmc+IGludDY0RmllbGRMaXN0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNYXBGaWVsZE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcEZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNYXBGaWVsZCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQpCiAgICAgIFRlc3RNYXBGaWVsZE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1hcEZpZWxkLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNYXBGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNYXBGaWVsZCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWFwRmllbGQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE1hcEZpZWxkT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkLk1hcEZpZWxkKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5NYXBGaWVsZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBGaWVsZCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkLk1hcEZpZWxkKQogICAgICAgIE1hcEZpZWxkT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTWFwRmllbGQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBNYXBGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE1hcEZpZWxkKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE1hcEZpZWxkKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX01hcEZpZWxkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQpIG9iajsKCiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5NYXBGaWVsZH0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkLk1hcEZpZWxkKQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGRPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZC5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NYXBGaWVsZF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQodGhpcyk7CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1hcEZpZWxkKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWFwRmllbGQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNYXBGaWVsZD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE1hcEZpZWxkPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE1hcEZpZWxkIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWFwRmllbGQ+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNYXBGaWVsZD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgUGFpck9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5QYWlyKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5QYWlyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFBhaXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5QYWlyKQogICAgICAgIFBhaXJPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBQYWlyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgUGFpcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIFBhaXIoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgUGFpcigpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX1BhaXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX1BhaXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIpIG9iajsKCiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpciBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkLlBhaXJ9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5QYWlyKQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpck9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfUGFpcl9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX1BhaXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpci5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9QYWlyX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIGJ1aWxkKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyKHRoaXMpOwogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpcilvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuUGFpci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5QYWlyKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkLlBhaXIpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5QYWlyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UGFpcj4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFBhaXI+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGFpciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFBhaXI+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQYWlyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLlBhaXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQuTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBpb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQuTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNZXNzYWdlIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQuTWVzc2FnZSkKICAgICAgICBNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlKSBvYmo7CgogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5NZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQuTWVzc2FnZSkKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX01lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkLk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQuTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZC5NZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TWFwRmllbGQoKSB7CiAgICAgIGlmIChtYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0TWFwRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaWVsZCgpLAogICAgICAgICAgTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBGaWVsZF9fID0gTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIG1hcEZpZWxkX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdE1hcEZpZWxkKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TWFwRmllbGQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpZWxkXyA9IGludGVybmFsR2V0TWFwRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5tYXBGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgbWFwRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBGaWVsZF9fLmdldEtleSgpLCBtYXBGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaWVsZCgpIHsKICAgICAgICBpZiAobWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKG1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBGaWVsZF8gPSBtYXBGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcEZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRNYXBGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVNYXBGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTppb19wcm90b2NvbF90ZXN0cy5UZXN0TWFwRmllbGQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RNYXBGaWVsZCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdE1hcEZpZWxkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNYXBGaWVsZD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWFwRmllbGQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwRmllbGQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwRmllbGQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcEZpZWxkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RNYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RMZWFkaW5nTnVtYmVyRmllbGRzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzMwZGF5X2ltcHJlc3Npb25zID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIDMwZGF5SW1wcmVzc2lvbnMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhczMwRGF5SW1wcmVzc2lvbnMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzMwZGF5X2ltcHJlc3Npb25zID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSAzMGRheUltcHJlc3Npb25zLgogICAgICovCiAgICBpbnQgZ2V0MzBEYXlJbXByZXNzaW9ucygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF82MGRheV9pbXByZXNzaW9ucyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgNjBkYXlJbXByZXNzaW9ucy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXQ2MERheUltcHJlc3Npb25zTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgXzYwZGF5X2ltcHJlc3Npb25zID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiA2MGRheUltcHJlc3Npb25zLgogICAgICovCiAgICBpbnQgZ2V0NjBEYXlJbXByZXNzaW9uc0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfNjBkYXlfaW1wcmVzc2lvbnMgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgNjBkYXlJbXByZXNzaW9ucyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0NjBEYXlJbXByZXNzaW9ucyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgXzYwZGF5X2ltcHJlc3Npb25zID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgNjBkYXlJbXByZXNzaW9ucyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldDYwRGF5SW1wcmVzc2lvbnNCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIF9fMl91bmRlcnNjb3JlcyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAyVW5kZXJzY29yZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhczJVbmRlcnNjb3JlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgX18yX3VuZGVyc2NvcmVzID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSAyVW5kZXJzY29yZXMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0MlVuZGVyc2NvcmVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBfXzJfdW5kZXJzY29yZXMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciAyVW5kZXJzY29yZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldDJVbmRlcnNjb3Jlc0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIDJyZXBlYXRlZFVuZGVyc2NvcmVzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldDJSZXBlYXRlZFVuZGVyc2NvcmVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIDJyZXBlYXRlZFVuZGVyc2NvcmVzLgogICAgICovCiAgICBpbnQgZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgMnJlcGVhdGVkVW5kZXJzY29yZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldDJSZXBlYXRlZFVuZGVyc2NvcmVzKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfXzJyZXBlYXRlZF91bmRlcnNjb3JlcyA9IDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIDJyZXBlYXRlZFVuZGVyc2NvcmVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXNCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgMzIuCiAgICAgKi8KICAgIGludCBnZXQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgNjQuCiAgICAgKi8KICAgIGludCBnZXQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IF82NCA9IDY0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldDY0KGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMpCiAgICAgIFRlc3RMZWFkaW5nTnVtYmVyRmllbGRzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TGVhZGluZ051bWJlckZpZWxkcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TGVhZGluZ051bWJlckZpZWxkcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKCkgewogICAgICBfNjBEYXlJbXByZXNzaW9uc18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBfMlVuZGVyc2NvcmVzXyA9ICIiOwogICAgICBfMlJlcGVhdGVkVW5kZXJzY29yZXNfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgXzY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TGVhZGluZ051bWJlckZpZWxkcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RMZWFkaW5nTnVtYmVyRmllbGRzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdExlYWRpbmdOdW1iZXJGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfMzBEQVlfSU1QUkVTU0lPTlNfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IF8zMERheUltcHJlc3Npb25zXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8zMGRheV9pbXByZXNzaW9ucyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAzMGRheUltcHJlc3Npb25zIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzMzBEYXlJbXByZXNzaW9ucygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfMzBkYXlfaW1wcmVzc2lvbnMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIDMwZGF5SW1wcmVzc2lvbnMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0MzBEYXlJbXByZXNzaW9ucygpIHsKICAgICAgcmV0dXJuIF8zMERheUltcHJlc3Npb25zXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBfNjBEQVlfSU1QUkVTU0lPTlNfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgXzYwRGF5SW1wcmVzc2lvbnNfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfNjBkYXlfaW1wcmVzc2lvbnMgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIDYwZGF5SW1wcmVzc2lvbnMuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldDYwRGF5SW1wcmVzc2lvbnNMaXN0KCkgewogICAgICByZXR1cm4gXzYwRGF5SW1wcmVzc2lvbnNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgXzYwZGF5X2ltcHJlc3Npb25zID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiA2MGRheUltcHJlc3Npb25zLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldDYwRGF5SW1wcmVzc2lvbnNDb3VudCgpIHsKICAgICAgcmV0dXJuIF82MERheUltcHJlc3Npb25zXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfNjBkYXlfaW1wcmVzc2lvbnMgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgNjBkYXlJbXByZXNzaW9ucyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldDYwRGF5SW1wcmVzc2lvbnMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBfNjBEYXlJbXByZXNzaW9uc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF82MGRheV9pbXByZXNzaW9ucyA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIDYwZGF5SW1wcmVzc2lvbnMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0NjBEYXlJbXByZXNzaW9uc0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gXzYwRGF5SW1wcmVzc2lvbnNfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF9fMl9VTkRFUlNDT1JFU19GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgXzJVbmRlcnNjb3Jlc18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIF9fMl91bmRlcnNjb3JlcyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSAyVW5kZXJzY29yZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXMyVW5kZXJzY29yZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIF9fMl91bmRlcnNjb3JlcyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgMlVuZGVyc2NvcmVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQyVW5kZXJzY29yZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gXzJVbmRlcnNjb3Jlc187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgXzJVbmRlcnNjb3Jlc18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgX18yX3VuZGVyc2NvcmVzID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgMlVuZGVyc2NvcmVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0MlVuZGVyc2NvcmVzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gXzJVbmRlcnNjb3Jlc187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIF8yVW5kZXJzY29yZXNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX18yUkVQRUFURURfVU5ERVJTQ09SRVNfRklFTERfTlVNQkVSID0gNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgXzJSZXBlYXRlZFVuZGVyc2NvcmVzXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIDJyZXBlYXRlZFVuZGVyc2NvcmVzLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXQyUmVwZWF0ZWRVbmRlcnNjb3Jlc0xpc3QoKSB7CiAgICAgIHJldHVybiBfMlJlcGVhdGVkVW5kZXJzY29yZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIDJyZXBlYXRlZFVuZGVyc2NvcmVzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldDJSZXBlYXRlZFVuZGVyc2NvcmVzQ291bnQoKSB7CiAgICAgIHJldHVybiBfMlJlcGVhdGVkVW5kZXJzY29yZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF9fMnJlcGVhdGVkX3VuZGVyc2NvcmVzID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIDJyZXBlYXRlZFVuZGVyc2NvcmVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBfMlJlcGVhdGVkVW5kZXJzY29yZXNfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfXzJyZXBlYXRlZF91bmRlcnNjb3JlcyA9IDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIDJyZXBlYXRlZFVuZGVyc2NvcmVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldDJSZXBlYXRlZFVuZGVyc2NvcmVzQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBfMlJlcGVhdGVkVW5kZXJzY29yZXNfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF8zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIHByaXZhdGUgaW50IF8zMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfMzIgPSAzMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0MzIoKSB7CiAgICAgIHJldHVybiBfMzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IF82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IF82NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBfNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiA2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXQ2NENvdW50KCkgewogICAgICByZXR1cm4gXzY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IF82NCA9IDY0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIF82NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBfMzBEYXlJbXByZXNzaW9uc18pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgXzYwRGF5SW1wcmVzc2lvbnNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBfNjBEYXlJbXByZXNzaW9uc18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDMsIF8yVW5kZXJzY29yZXNfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDQsIF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzMiwgXzMyXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoNjQsIF82NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgXzMwRGF5SW1wcmVzc2lvbnNfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF82MERheUltcHJlc3Npb25zXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhfNjBEYXlJbXByZXNzaW9uc18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXQ2MERheUltcHJlc3Npb25zTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDMsIF8yVW5kZXJzY29yZXNfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcoXzJSZXBlYXRlZFVuZGVyc2NvcmVzXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldDJSZXBlYXRlZFVuZGVyc2NvcmVzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMyLCBfMzJfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF82NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhfNjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMpIG9iajsKCiAgICAgIGlmIChoYXMzMERheUltcHJlc3Npb25zKCkgIT0gb3RoZXIuaGFzMzBEYXlJbXByZXNzaW9ucygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXMzMERheUltcHJlc3Npb25zKCkpIHsKICAgICAgICBpZiAoZ2V0MzBEYXlJbXByZXNzaW9ucygpCiAgICAgICAgICAgICE9IG90aGVyLmdldDMwRGF5SW1wcmVzc2lvbnMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0NjBEYXlJbXByZXNzaW9uc0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXQ2MERheUltcHJlc3Npb25zTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzMlVuZGVyc2NvcmVzKCkgIT0gb3RoZXIuaGFzMlVuZGVyc2NvcmVzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhczJVbmRlcnNjb3JlcygpKSB7CiAgICAgICAgaWYgKCFnZXQyVW5kZXJzY29yZXMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldDJVbmRlcnNjb3JlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXNMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXMzMigpICE9IG90aGVyLmhhczMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhczMyKCkpIHsKICAgICAgICBpZiAoZ2V0MzIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzMzBEYXlJbXByZXNzaW9ucygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgXzMwREFZX0lNUFJFU1NJT05TX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXQzMERheUltcHJlc3Npb25zKCk7CiAgICAgIH0KICAgICAgaWYgKGdldDYwRGF5SW1wcmVzc2lvbnNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIF82MERBWV9JTVBSRVNTSU9OU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0NjBEYXlJbXByZXNzaW9uc0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXMyVW5kZXJzY29yZXMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIF9fMl9VTkRFUlNDT1JFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0MlVuZGVyc2NvcmVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIF9fMlJFUEVBVEVEX1VOREVSU0NPUkVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXQyUmVwZWF0ZWRVbmRlcnNjb3Jlc0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXMzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgXzMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXQzMigpOwogICAgICB9CiAgICAgIGlmIChnZXQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgXzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TGVhZGluZ051bWJlckZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgaW9fcHJvdG9jb2xfdGVzdHMuVGVzdExlYWRpbmdOdW1iZXJGaWVsZHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czppb19wcm90b2NvbF90ZXN0cy5UZXN0TGVhZGluZ051bWJlckZpZWxkcykKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RMZWFkaW5nTnVtYmVyRmllbGRzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RMZWFkaW5nTnVtYmVyRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBfMzBEYXlJbXByZXNzaW9uc18gPSAwOwogICAgICAgIF82MERheUltcHJlc3Npb25zXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBfMlVuZGVyc2NvcmVzXyA9ICIiOwogICAgICAgIF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgXzMyXyA9IDA7CiAgICAgICAgXzY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5pbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdExlYWRpbmdOdW1iZXJGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TGVhZGluZ051bWJlckZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuXzMwRGF5SW1wcmVzc2lvbnNfID0gXzMwRGF5SW1wcmVzc2lvbnNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgXzYwRGF5SW1wcmVzc2lvbnNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5fNjBEYXlJbXByZXNzaW9uc18gPSBfNjBEYXlJbXByZXNzaW9uc187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuXzJVbmRlcnNjb3Jlc18gPSBfMlVuZGVyc2NvcmVzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0Ll8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18gPSBfMlJlcGVhdGVkVW5kZXJzY29yZXNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Ll8zMl8gPSBfMzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgXzY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuXzY0XyA9IF82NF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TGVhZGluZ051bWJlckZpZWxkcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhczMwRGF5SW1wcmVzc2lvbnMoKSkgewogICAgICAgICAgc2V0MzBEYXlJbXByZXNzaW9ucyhvdGhlci5nZXQzMERheUltcHJlc3Npb25zKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLl82MERheUltcHJlc3Npb25zXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChfNjBEYXlJbXByZXNzaW9uc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIF82MERheUltcHJlc3Npb25zXyA9IG90aGVyLl82MERheUltcHJlc3Npb25zXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlNjBEYXlJbXByZXNzaW9uc0lzTXV0YWJsZSgpOwogICAgICAgICAgICBfNjBEYXlJbXByZXNzaW9uc18uYWRkQWxsKG90aGVyLl82MERheUltcHJlc3Npb25zXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhczJVbmRlcnNjb3JlcygpKSB7CiAgICAgICAgICBfMlVuZGVyc2NvcmVzXyA9IG90aGVyLl8yVW5kZXJzY29yZXNfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuXzJSZXBlYXRlZFVuZGVyc2NvcmVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChfMlJlcGVhdGVkVW5kZXJzY29yZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBfMlJlcGVhdGVkVW5kZXJzY29yZXNfID0gb3RoZXIuXzJSZXBlYXRlZFVuZGVyc2NvcmVzXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlMlJlcGVhdGVkVW5kZXJzY29yZXNJc011dGFibGUoKTsKICAgICAgICAgICAgXzJSZXBlYXRlZFVuZGVyc2NvcmVzXy5hZGRBbGwob3RoZXIuXzJSZXBlYXRlZFVuZGVyc2NvcmVzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhczMyKCkpIHsKICAgICAgICAgIHNldDMyKG90aGVyLmdldDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLl82NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoXzY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgXzY0XyA9IG90aGVyLl82NF87CiAgICAgICAgICAgIF82NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmU2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBfNjRfLmFkZEFsbChvdGhlci5fNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIF8zMERheUltcHJlc3Npb25zXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZTYwRGF5SW1wcmVzc2lvbnNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIF82MERheUltcHJlc3Npb25zXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgXzJVbmRlcnNjb3Jlc18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlMlJlcGVhdGVkVW5kZXJzY29yZXNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgMjU2OiB7CiAgICAgICAgICAgICAgICBfMzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU2CiAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIF82NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBjYXNlIDUxNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmU2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBfNjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBfMzBEYXlJbXByZXNzaW9uc18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgXzMwZGF5X2ltcHJlc3Npb25zID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgMzBkYXlJbXByZXNzaW9ucyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhczMwRGF5SW1wcmVzc2lvbnMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfMzBkYXlfaW1wcmVzc2lvbnMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgMzBkYXlJbXByZXNzaW9ucy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXQzMERheUltcHJlc3Npb25zKCkgewogICAgICAgIHJldHVybiBfMzBEYXlJbXByZXNzaW9uc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8zMGRheV9pbXByZXNzaW9ucyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIDMwZGF5SW1wcmVzc2lvbnMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXQzMERheUltcHJlc3Npb25zKGludCB2YWx1ZSkgewoKICAgICAgICBfMzBEYXlJbXByZXNzaW9uc18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8zMGRheV9pbXByZXNzaW9ucyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcjMwRGF5SW1wcmVzc2lvbnMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIF8zMERheUltcHJlc3Npb25zXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IF82MERheUltcHJlc3Npb25zXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmU2MERheUltcHJlc3Npb25zSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghXzYwRGF5SW1wcmVzc2lvbnNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBfNjBEYXlJbXByZXNzaW9uc18gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KF82MERheUltcHJlc3Npb25zXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF82MGRheV9pbXByZXNzaW9ucyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSA2MGRheUltcHJlc3Npb25zLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXQ2MERheUltcHJlc3Npb25zTGlzdCgpIHsKICAgICAgICBfNjBEYXlJbXByZXNzaW9uc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBfNjBEYXlJbXByZXNzaW9uc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfNjBkYXlfaW1wcmVzc2lvbnMgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgNjBkYXlJbXByZXNzaW9ucy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0NjBEYXlJbXByZXNzaW9uc0NvdW50KCkgewogICAgICAgIHJldHVybiBfNjBEYXlJbXByZXNzaW9uc18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgXzYwZGF5X2ltcHJlc3Npb25zID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSA2MGRheUltcHJlc3Npb25zIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldDYwRGF5SW1wcmVzc2lvbnMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIF82MERheUltcHJlc3Npb25zXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgXzYwZGF5X2ltcHJlc3Npb25zID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIDYwZGF5SW1wcmVzc2lvbnMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0NjBEYXlJbXByZXNzaW9uc0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBfNjBEYXlJbXByZXNzaW9uc18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfNjBkYXlfaW1wcmVzc2lvbnMgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIDYwZGF5SW1wcmVzc2lvbnMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXQ2MERheUltcHJlc3Npb25zKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmU2MERheUltcHJlc3Npb25zSXNNdXRhYmxlKCk7CiAgICAgICAgXzYwRGF5SW1wcmVzc2lvbnNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF82MGRheV9pbXByZXNzaW9ucyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIDYwZGF5SW1wcmVzc2lvbnMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGQ2MERheUltcHJlc3Npb25zKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlNjBEYXlJbXByZXNzaW9uc0lzTXV0YWJsZSgpOwogICAgICAgIF82MERheUltcHJlc3Npb25zXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF82MGRheV9pbXByZXNzaW9ucyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSA2MGRheUltcHJlc3Npb25zIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsNjBEYXlJbXByZXNzaW9ucygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmU2MERheUltcHJlc3Npb25zSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIF82MERheUltcHJlc3Npb25zXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgXzYwZGF5X2ltcHJlc3Npb25zID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyNjBEYXlJbXByZXNzaW9ucygpIHsKICAgICAgICBfNjBEYXlJbXByZXNzaW9uc18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfNjBkYXlfaW1wcmVzc2lvbnMgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgNjBkYXlJbXByZXNzaW9ucyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZDYwRGF5SW1wcmVzc2lvbnNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlNjBEYXlJbXByZXNzaW9uc0lzTXV0YWJsZSgpOwogICAgICAgIF82MERheUltcHJlc3Npb25zXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IF8yVW5kZXJzY29yZXNfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgX18yX3VuZGVyc2NvcmVzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgMlVuZGVyc2NvcmVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhczJVbmRlcnNjb3JlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBfXzJfdW5kZXJzY29yZXMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgMlVuZGVyc2NvcmVzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0MlVuZGVyc2NvcmVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gXzJVbmRlcnNjb3Jlc187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBfMlVuZGVyc2NvcmVzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgX18yX3VuZGVyc2NvcmVzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciAyVW5kZXJzY29yZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXQyVW5kZXJzY29yZXNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IF8yVW5kZXJzY29yZXNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBfMlVuZGVyc2NvcmVzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBfXzJfdW5kZXJzY29yZXMgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSAyVW5kZXJzY29yZXMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXQyVW5kZXJzY29yZXMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBfMlVuZGVyc2NvcmVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIF9fMl91bmRlcnNjb3JlcyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcjJVbmRlcnNjb3JlcygpIHsKICAgICAgICBfMlVuZGVyc2NvcmVzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldDJVbmRlcnNjb3JlcygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIF9fMl91bmRlcnNjb3JlcyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciAyVW5kZXJzY29yZXMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXQyVW5kZXJzY29yZXNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgXzJVbmRlcnNjb3Jlc18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlMlJlcGVhdGVkVW5kZXJzY29yZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFfMlJlcGVhdGVkVW5kZXJzY29yZXNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBfMlJlcGVhdGVkVW5kZXJzY29yZXNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChfMlJlcGVhdGVkVW5kZXJzY29yZXNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgMnJlcGVhdGVkVW5kZXJzY29yZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldDJSZXBlYXRlZFVuZGVyc2NvcmVzTGlzdCgpIHsKICAgICAgICBfMlJlcGVhdGVkVW5kZXJzY29yZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gXzJSZXBlYXRlZFVuZGVyc2NvcmVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF9fMnJlcGVhdGVkX3VuZGVyc2NvcmVzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIDJyZXBlYXRlZFVuZGVyc2NvcmVzLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXQyUmVwZWF0ZWRVbmRlcnNjb3Jlc0NvdW50KCkgewogICAgICAgIHJldHVybiBfMlJlcGVhdGVkVW5kZXJzY29yZXNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF9fMnJlcGVhdGVkX3VuZGVyc2NvcmVzID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSAycmVwZWF0ZWRVbmRlcnNjb3JlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQyUmVwZWF0ZWRVbmRlcnNjb3JlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gXzJSZXBlYXRlZFVuZGVyc2NvcmVzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgMnJlcGVhdGVkVW5kZXJzY29yZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0MlJlcGVhdGVkVW5kZXJzY29yZXNCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gXzJSZXBlYXRlZFVuZGVyc2NvcmVzXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIF9fMnJlcGVhdGVkX3VuZGVyc2NvcmVzID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSAycmVwZWF0ZWRVbmRlcnNjb3JlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldDJSZXBlYXRlZFVuZGVyc2NvcmVzKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmUyUmVwZWF0ZWRVbmRlcnNjb3Jlc0lzTXV0YWJsZSgpOwogICAgICAgIF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSAycmVwZWF0ZWRVbmRlcnNjb3JlcyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZDJSZXBlYXRlZFVuZGVyc2NvcmVzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlMlJlcGVhdGVkVW5kZXJzY29yZXNJc011dGFibGUoKTsKICAgICAgICBfMlJlcGVhdGVkVW5kZXJzY29yZXNfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgX18ycmVwZWF0ZWRfdW5kZXJzY29yZXMgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgMnJlcGVhdGVkVW5kZXJzY29yZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGwyUmVwZWF0ZWRVbmRlcnNjb3JlcygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmUyUmVwZWF0ZWRVbmRlcnNjb3Jlc0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBfMlJlcGVhdGVkVW5kZXJzY29yZXNfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfXzJyZXBlYXRlZF91bmRlcnNjb3JlcyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcjJSZXBlYXRlZFVuZGVyc2NvcmVzKCkgewogICAgICAgIF8yUmVwZWF0ZWRVbmRlcnNjb3Jlc18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBfXzJyZXBlYXRlZF91bmRlcnNjb3JlcyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSAycmVwZWF0ZWRVbmRlcnNjb3JlcyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZDJSZXBlYXRlZFVuZGVyc2NvcmVzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZTJSZXBlYXRlZFVuZGVyc2NvcmVzSXNNdXRhYmxlKCk7CiAgICAgICAgXzJSZXBlYXRlZFVuZGVyc2NvcmVzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgXzMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXMzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8zMiA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgMzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0MzIoKSB7CiAgICAgICAgcmV0dXJuIF8zMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF8zMiA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSAzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldDMyKGludCB2YWx1ZSkgewoKICAgICAgICBfMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIF8zMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgXzY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZTY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghXzY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgXzY0XyA9IG1ha2VNdXRhYmxlQ29weShfNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0NjRMaXN0KCkgewogICAgICAgIF82NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBfNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBfNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIF82NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IF82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlNjRJc011dGFibGUoKTsKICAgICAgICBfNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IF82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSA2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlNjRJc011dGFibGUoKTsKICAgICAgICBfNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSA2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgXzY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyNjQoKSB7CiAgICAgICAgXzY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdExlYWRpbmdOdW1iZXJGaWVsZHMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmlvX3Byb3RvY29sX3Rlc3RzLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5UZXN0TGVhZGluZ051bWJlckZpZWxkcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdExlYWRpbmdOdW1iZXJGaWVsZHM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdExlYWRpbmdOdW1iZXJGaWVsZHM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TGVhZGluZ051bWJlckZpZWxkcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RMZWFkaW5nTnVtYmVyRmllbGRzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RMZWFkaW5nTnVtYmVyRmllbGRzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RMZWFkaW5nTnVtYmVyRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIC8qKgogICAqIFByb3RvYnVmIHNlcnZpY2Uge0Bjb2RlIGlvX3Byb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ01ldGhvZE5hbWVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgVGVzdENvbmZsaWN0aW5nTWV0aG9kTmFtZXMKICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2UgewogICAgcHJvdGVjdGVkIFRlc3RDb25mbGljdGluZ01ldGhvZE5hbWVzKCkge30KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEludGVyZmFjZSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ycGMgT3ZlcnJpZGUoLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UpIHJldHVybnMgKC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBvdmVycmlkZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHJlcXVlc3QsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gZG9uZSk7CgogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlIG5ld1JlZmxlY3RpdmVTZXJ2aWNlKAogICAgICAgIGZpbmFsIEludGVyZmFjZSBpbXBsKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdENvbmZsaWN0aW5nTWV0aG9kTmFtZXMoKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyAgdm9pZCBvdmVycmlkZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSByZXF1ZXN0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZT4gZG9uZSkgewogICAgICAgICAgaW1wbC5vdmVycmlkZShjb250cm9sbGVyLCByZXF1ZXN0LCBkb25lKTsKICAgICAgICB9CgogICAgICB9OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1NlcnZpY2UKICAgICAgICBuZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlKGZpbmFsIEJsb2NraW5nSW50ZXJmYWNlIGltcGwpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nU2VydmljZSgpIHsKICAgICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIGNhbGxCbG9ja2luZ01ldGhvZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSByZXF1ZXN0KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiU2VydmljZS5jYWxsQmxvY2tpbmdNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3IgIiArCiAgICAgICAgICAgICAgIndyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgcmV0dXJuIGltcGwub3ZlcnJpZGUoY29udHJvbGxlciwgKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSlyZXF1ZXN0KTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UKICAgICAgICAgICAgZ2V0UmVxdWVzdFByb3RvdHlwZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJTZXJ2aWNlLmdldFJlcXVlc3RQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgIiArCiAgICAgICAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UKICAgICAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiU2VydmljZS5nZXRSZXNwb25zZVByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCAiICsKICAgICAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgIH07CiAgICB9CgogICAgLyoqCiAgICAgKiA8Y29kZT5ycGMgT3ZlcnJpZGUoLmlvX3Byb3RvY29sX3Rlc3RzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UpIHJldHVybnMgKC5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlKTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG92ZXJyaWRlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSByZXF1ZXN0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPiBkb25lKTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLmdldERlc2NyaXB0b3IoKS5nZXRTZXJ2aWNlcygpLmdldCgwKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLlNlcnZpY2VEZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CgogICAgcHVibGljIGZpbmFsIHZvaWQgY2FsbE1ldGhvZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSByZXF1ZXN0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2U+IGRvbmUpIHsKICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiU2VydmljZS5jYWxsTWV0aG9kKCkgZ2l2ZW4gbWV0aG9kIGRlc2NyaXB0b3IgZm9yIHdyb25nICIgKwogICAgICAgICAgInNlcnZpY2UgdHlwZS4iKTsKICAgICAgfQogICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICB0aGlzLm92ZXJyaWRlKGNvbnRyb2xsZXIsIChjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UpcmVxdWVzdCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNVdGlsLjxjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2U+c3BlY2lhbGl6ZUNhbGxiYWNrKAogICAgICAgICAgICAgIGRvbmUpKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgICAgZ2V0UmVxdWVzdFByb3RvdHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKSB7CiAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIlNlcnZpY2UuZ2V0UmVxdWVzdFByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCAiICsKICAgICAgICAgICJkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgIH0KICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJTZXJ2aWNlLmdldFJlc3BvbnNlUHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgfQogICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgU3R1YiBuZXdTdHViKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgIHJldHVybiBuZXcgU3R1YihjaGFubmVsKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0dWIgZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLlRlc3RDb25mbGljdGluZ01ldGhvZE5hbWVzIGltcGxlbWVudHMgSW50ZXJmYWNlIHsKICAgICAgcHJpdmF0ZSBTdHViKGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgY2hhbm5lbDsKCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKICAgICAgICByZXR1cm4gY2hhbm5lbDsKICAgICAgfQoKICAgICAgcHVibGljICB2b2lkIG92ZXJyaWRlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcmVxdWVzdCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8Y29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlPiBkb25lKSB7CiAgICAgICAgY2hhbm5lbC5jYWxsTWV0aG9kKAogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoMCksCiAgICAgICAgICBjb250cm9sbGVyLAogICAgICAgICAgcmVxdWVzdCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjVXRpbC5nZW5lcmFsaXplQ2FsbGJhY2soCiAgICAgICAgICAgIGRvbmUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZS5jbGFzcywKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIEJsb2NraW5nSW50ZXJmYWNlIG5ld0Jsb2NraW5nU3R1YigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgIHJldHVybiBuZXcgQmxvY2tpbmdTdHViKGNoYW5uZWwpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgQmxvY2tpbmdJbnRlcmZhY2UgewogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIG92ZXJyaWRlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRlc3RCYWRJZGVudGlmaWVyc1Byb3RvLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2UgcmVxdWVzdCkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VFeGNlcHRpb247CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQmxvY2tpbmdTdHViIGltcGxlbWVudHMgQmxvY2tpbmdJbnRlcmZhY2UgewogICAgICBwcml2YXRlIEJsb2NraW5nU3R1Yihjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nUnBjQ2hhbm5lbCBjaGFubmVsOwoKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSBvdmVycmlkZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlIHJlcXVlc3QpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZSkgY2hhbm5lbC5jYWxsQmxvY2tpbmdNZXRob2QoCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWV0aG9kcygpLmdldCgwKSwKICAgICAgICAgIGNvbnRyb2xsZXIsCiAgICAgICAgICByZXF1ZXN0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UZXN0QmFkSWRlbnRpZmllcnNQcm90by5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQoKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6aW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nTWV0aG9kTmFtZXMpCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc0NhbWVsTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXNjcmlwdG9yX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXNjcmlwdG9yX05lc3RlZERlc2NyaXB0b3JfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9OZXN0ZWREZXNjcmlwdG9yX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19QYXJzZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfUGFyc2VyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXByZWNhdGVkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0RlcHJlY2F0ZWRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX092ZXJyaWRlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX092ZXJyaWRlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19PYmplY3RfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT2JqZWN0X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19TdHJpbmdfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfU3RyaW5nX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19JbnRlZ2VyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ludGVnZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0xvbmdfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfTG9uZ19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0RvdWJsZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Eb3VibGVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX1BhaXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX1BhaXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdExlYWRpbmdOdW1iZXJGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdExlYWRpbmdOdW1iZXJGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi5jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfYmFkX2lkZW50aWZpZSIgKwogICAgICAicnMucHJvdG9cMDIyXDAyMWlvX3Byb3RvY29sX3Rlc3RzXCJcMjEwXDAwMlxuXDAzN0ZvcmJpZGRlIiArCiAgICAgICJuV29yZHNVbmRlcnNjb3JlTWVzc2FnZVwwMjJcclxuXDAwNWNsYXNzXDAzMFwwMDEgXDAwMShcMDEwXDAyMiEiICsKICAgICAgIlxuXDAzMWRlZmF1bHRfaW5zdGFuY2VfZm9yX3R5cGVcMDMwXDAwMiBcMDAxKFwwMTBcMDIyXDAyN1xuXDAxN3BhciIgKwogICAgICAic2VyX2Zvcl90eXBlXDAzMFwwMDMgXDAwMShcMDEwXDAyMlwwMjdcblwwMTdzZXJpYWxpemVkX3NpemVcMDMwXDAwNCAiICsKICAgICAgIlwwMDEoXDAxMFwwMjJcMDIyXG5cbmFsbF9maWVsZHNcMDMwXDAwNSBcMDAxKFwwMTBcMDIyXDAzM1xuXDAyM2Rlc2NyaXB0b3JfZm8iICsKICAgICAgInJfdHlwZVwwMzBcMDA2IFwwMDEoXDAxMFwwMjIjXG5cMDMzaW5pdGlhbGl6YXRpb25fZXJyb3Jfc3RyIiArCiAgICAgICJpbmdcMDMwXDAwNyBcMDAxKFwwMTBcMDIyXDAyNlxuXDAxNnVua25vd25fZmllbGRzXDAzMFwwMTAgXDAwMShcMDEwXDAyMlwwMjNcblwwMTNjYWMiICsKICAgICAgImhlZF9zaXplXDAzMFx0IFwwMDEoXDAxMFwiXDM3N1wwMDFcbiZGb3JiaWRkZW5Xb3Jkc0xlYWRpbmciICsKICAgICAgIlVuZGVyc2NvcmVNZXNzYWdlXDAyMlwwMTZcblwwMDZfY2xhc3NcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXCJcblwwMzJfZGUiICsKICAgICAgImZhdWx0X2luc3RhbmNlX2Zvcl90eXBlXDAzMFwwMDIgXDAwMShcMDEwXDAyMlwwMzBcblwwMjBfcGFyc2VyIiArCiAgICAgICJfZm9yX3R5cGVcMDMwXDAwMyBcMDAxKFwwMTBcMDIyXDAzMFxuXDAyMF9zZXJpYWxpemVkX3NpemVcMDMwXDAwNCBcMDAxKCIgKwogICAgICAiXDAxMFwwMjJcMDIzXG5cMDEzX2FsbF9maWVsZHNcMDMwXDAwNSBcMDAxKFwwMTBcMDIyXDAzNFxuXDAyNF9kZXNjcmlwdG9yX2ZvIiArCiAgICAgICJyX3R5cGVcMDMwXDAwNiBcMDAxKFwwMTBcMDIyJFxuXDAzNF9pbml0aWFsaXphdGlvbl9lcnJvcl9zdCIgKwogICAgICAicmluZ1wwMzBcMDA3IFwwMDEoXDAxMFwwMjJcMDI0XG5cMDE0X2NhY2hlZF9zaXplXDAzMFx0IFwwMDEoXDAxMFwiXDMzN1wwMDFcblwwMzJGb3IiICsKICAgICAgImJpZGRlbldvcmRzQ2FtZWxNZXNzYWdlXDAyMlxyXG5cMDA1Y2xhc3NcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXDAzNiIgKwogICAgICAiXG5cMDI2ZGVmYXVsdEluc3RhbmNlRm9yVHlwZVwwMzBcMDAyIFwwMDEoXDAxMFwwMjJcMDI2XG5cMDE2c2VyaWFsIiArCiAgICAgICJpemVkU2l6ZVwwMzBcMDAzIFwwMDEoXDAxMFwwMjJcMDI1XG5ccnBhcnNlckZvclR5cGVcMDMwXDAwNCBcMDAxKFwwMTBcMDIyIVxuIiArCiAgICAgICJcMDMxaW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ1wwMzBcMDA1IFwwMDEoXDAxMFwwMjJcMDMxXG5cMDIxZGVzYyIgKwogICAgICAicmlwdG9yRm9yVHlwZVwwMzBcMDA2IFwwMDEoXDAxMFwwMjJcMDIxXG5cdGFsbEZpZWxkc1wwMzBcMDA3IFwwMDEoXDAxMFwwMjJcMDIyIiArCiAgICAgICJcblxuY2FjaGVkU2l6ZVwwMzBcdCBcMDAxKFwwMTBcIlwyNzdcMDAxXG5cbkRlc2NyaXB0b3JcMDIyXDAyMlxuXG5kZXMiICsKICAgICAgImNyaXB0b3JcMDMwXDAwMSBcMDAxKFx0XDAyMklcblwwMjFuZXN0ZWRfZGVzY3JpcHRvclwwMzBcMDAyIFwwMDEoXDAxMyIgKwogICAgICAiMi4uaW9fcHJvdG9jb2xfdGVzdHMuRGVzY3JpcHRvci5OZXN0ZWREZSIgKwogICAgICAic2NyaXB0b3JcMDMyKlxuXDAyME5lc3RlZERlc2NyaXB0b3JcMDIyXDAyMlxuXG5kZXNjcmlwdCIgKwogICAgICAib3JcMDMwXDAwMSBcMDAxKFx0OlwwMDJcMDIwXDAwMVwiXCJcblxuTmVzdGVkRW51bVwwMjJcMDEzXG5cMDA3VU5LTk9XTlwwMjBcMDAwXDAyMiIgKwogICAgICAiXDAwN1xuXDAwM0ZPT1wwMjBcMDAxOlwwMDJcMDIwXDAwMVwiZVxuXDAwNlBhcnNlclwwMjI0XG5cMDA2cGFyc2VyXDAzMFwwMDEgXDAwMShcMDE2MiQiICsKICAgICAgIi5pb19wcm90b2NvbF90ZXN0cy5QYXJzZXIuUGFyc2VyRW51bVwiJVxuXG4iICsKICAgICAgIlBhcnNlckVudW1cMDIyXDAxM1xuXDAwN1VOS05PV05cMDIwXDAwMFwwMjJcblxuXDAwNlBBUlNFUlwwMjBcMDAxXCJcMzIzXDAwMVxuXG4iICsKICAgICAgIkRlcHJlY2F0ZWRcMDIyXDAyMlxuXDAwNmZpZWxkMVwwMzBcMDAxIFwwMDEoXDAwNUJcMDAyXDAzMFwwMDFcMDIyOlxuXDAwNmZpZWxkMiIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDE2MiYuaW9fcHJvdG9jb2xfdGVzdHMuRGVwcmVjYXRlZC5UZSIgKwogICAgICAic3RFbnVtQlwwMDJcMDMwXDAwMVwwMjJGXG5cMDA2ZmllbGQzXDAzMFwwMDMgXDAwMShcMDEzMjIuaW9fcHJvdG9jb2wiICsKICAgICAgIl90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlQlwwMDIiICsKICAgICAgIlwwMzBcMDAxXCItXG5cMDEwVGVzdEVudW1cMDIyXDAxM1xuXDAwN1VOS05PV05cMDIwXDAwMFwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDFcMDIyXDAxM1xuXDAwMyIgKwogICAgICAiQkFSXDAyMFwwMDJcMDMyXDAwMlwwMTBcMDAxXCJcMDM0XG5cMDEwT3ZlcnJpZGVcMDIyXDAyMFxuXDAxMG92ZXJyaWRlXDAzMFwwMDEgXDAwMShcMDA1XCIiICsKICAgICAgIi9cblwwMDZPYmplY3RcMDIyXDAxNlxuXDAwNm9iamVjdFwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDI1XG5ccnN0cmluZ19vYmplIiArCiAgICAgICJjdFwwMzBcMDAyIFwwMDEoXHRcIlwwMzBcblwwMDZTdHJpbmdcMDIyXDAxNlxuXDAwNnN0cmluZ1wwMzBcMDAxIFwwMDEoXHRcIlwwMzJcblwwMDdJbiIgKwogICAgICAidGVnZXJcMDIyXDAxN1xuXDAwN2ludGVnZXJcMDMwXDAwMSBcMDAxKFwwMDVcIlwwMjRcblwwMDRMb25nXDAyMlwwMTRcblwwMDRsb25nXDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMDVcIlwwMjZcblwwMDVGbG9hdFwwMjJcclxuXDAwNWZsb2F0XDAzMFwwMDEgXDAwMShcMDAyXCJcMDMwXG5cMDA2RG91YmxlXDAyMlwwMTYiICsKICAgICAgIlxuXDAwNmRvdWJsZVwwMzBcMDAxIFwwMDEoXDAwMVwiXDM1NFwwMTBcblwwMzFUZXN0Q29uZmxpY3RpbmdGaWVsZE4iICsKICAgICAgImFtZXNcMDIyXDAyM1xuXDAxM2ludDMyX2ZpZWxkXDAzMFwwMDEgXDAwMyhcMDA1XDAyMklcblxuZW51bV9maWVsZFwwMzAiICsKICAgICAgIlwwMDIgXDAwMyhcMDE2MjUuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW4iICsKICAgICAgImdGaWVsZE5hbWVzLlRlc3RFbnVtXDAyMlwwMjRcblwwMTRzdHJpbmdfZmllbGRcMDMwXDAwMyBcMDAzIiArCiAgICAgICIoXHRcMDIyXDAyM1xuXDAxM2J5dGVzX2ZpZWxkXDAzMFwwMDQgXDAwMyhcMDE0XDAyMmNcblxybWVzc2FnZV9maWVsZCIgKwogICAgICAiXDAzMFwwMDUgXDAwMyhcMDEzMkwuaW9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aSIgKwogICAgICAibmdGaWVsZE5hbWVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lcyIgKwogICAgICAic2FnZVwwMjJcMDMxXG5cMDIxaW50MzJfZmllbGRfY291bnRcMDMwXDAxMyBcMDAxKFwwMDVcMDIyT1xuXDAyMGVudW1fIiArCiAgICAgICJmaWVsZF9jb3VudFwwMzBcMDE0IFwwMDEoXDAxNjI1LmlvX3Byb3RvY29sX3Rlc3RzLlRlIiArCiAgICAgICJzdENvbmZsaWN0aW5nRmllbGROYW1lcy5UZXN0RW51bVwwMjJcMDMyXG5cMDIyc3RyaSIgKwogICAgICAibmdfZmllbGRfY291bnRcMDMwXHIgXDAwMShcdFwwMjJcMDMxXG5cMDIxYnl0ZXNfZmllbGRfY291biIgKwogICAgICAidFwwMzBcMDE2IFwwMDEoXDAxNFwwMjJpXG5cMDIzbWVzc2FnZV9maWVsZF9jb3VudFwwMzBcMDE3IFwwMDEoXDAxMzJMLmkiICsKICAgICAgIm9fcHJvdG9jb2xfdGVzdHMuVGVzdENvbmZsaWN0aW5nRmllbGROYW0iICsKICAgICAgImVzLkZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VcMDIyXDAyMlxuXG5JbiIgKwogICAgICAidDMyRmllbGRcMDMwXDAyNSBcMDAzKFwwMDVcMDIySFxuXHRFbnVtRmllbGRcMDMwXDAyNiBcMDAzKFwwMTYyNS5pb19wIiArCiAgICAgICJyb3RvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuIiArCiAgICAgICJUZXN0RW51bVwwMjJcMDIzXG5cMDEzU3RyaW5nRmllbGRcMDMwXDAyNyBcMDAzKFx0XDAyMlwwMjJcblxuQnl0ZXNGaSIgKwogICAgICAiZWxkXDAzMFwwMzAgXDAwMyhcMDE0XDAyMmJcblwwMTRNZXNzYWdlRmllbGRcMDMwXDAzMSBcMDAzKFwwMTMyTC5pb19wcm8iICsKICAgICAgInRvY29sX3Rlc3RzLlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXMuRm8iICsKICAgICAgInJiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlXDAyMlwwMzBcblwwMjBpbnQzMl9mIiArCiAgICAgICJpZWxkX2xpc3RcMDMwXDAzNyBcMDAyKFwwMDVcMDIyXDAyMlxuXG5maWVsZF9uYW1lXDAzMCAgXDAwMShcdFwwMjJcMDIzXG5cMDEzZiIgKwogICAgICAiaWVsZF9fbmFtZVwwMzAhIFwwMDEoXHRcMDIyXDAyMlxuXG5fMmNvbmZsaWN0XDAzMFwiIFwwMDEoXDAwNVwwMjJcMDIzXG5cMDEzIiArCiAgICAgICJfXzJjb25mbGljdFwwMzAjIFwwMDEoXDAwNVwwMjJcMDIzXG5cMDEzaW50NjRfZmllbGRcMDMwKSBcMDAzKFwwMDNcMDMyISIgKwogICAgICAiXG5cMDM3Rm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZVwiIFxuXDAxMFRlcyIgKwogICAgICAidEVudW1cMDIyXDAxM1xuXDAwN1VOS05PV05cMDIwXDAwMFwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDEqXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIySCIgKwogICAgICAiXG5cMDIxaW50NjRfZmllbGRfY291bnRcMDIyLC5pb19wcm90b2NvbF90ZXN0cy4iICsKICAgICAgIlRlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNcMDMwXDM1MVwwMDcgXDAwMShcMDAzMkdcblwwMjBpbnQ2IiArCiAgICAgICI0X2ZpZWxkX2xpc3RcMDIyLC5pb19wcm90b2NvbF90ZXN0cy5UZXN0Q29uIiArCiAgICAgICJmbGljdGluZ0ZpZWxkTmFtZXNcMDMwXDM1MlwwMDcgXDAwMShcMDAzOlwwMDJYXDAwMVwiXDI0MFwwMDFcblwwMTRUZXN0TWEiICsKICAgICAgInBGaWVsZFwwMjJAXG5cdG1hcF9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzItLmlvX3Byb3RvY29sXyIgKwogICAgICAidGVzdHMuVGVzdE1hcEZpZWxkLk1hcEZpZWxkRW50cnlcMDMyXG5cblwwMTBNYXBGIiArCiAgICAgICJpZWxkXDAzMlwwMDZcblwwMDRQYWlyXDAzMlx0XG5cMDA3TWVzc2FnZVwwMzIvXG5cck1hcEZpZWxkRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXCJcMjQ1XDAwMVxuXDAyN1RlcyIgKwogICAgICAidExlYWRpbmdOdW1iZXJGaWVsZHNcMDIyXDAzMlxuXDAyMl8zMGRheV9pbXByZXNzaW8iICsKICAgICAgIm5zXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMzJcblwwMjJfNjBkYXlfaW1wcmVzc2lvbnNcMDMwXDAwMiBcMDAzKFx0XDAyMlwwMjdcblwwMTciICsKICAgICAgIl9fMl91bmRlcnNjb3Jlc1wwMzBcMDAzIFwwMDEoXHRcMDIyXDAzN1xuXDAyN19fMnJlcGVhdGVkX3VuZCIgKwogICAgICAiZXJzY29yZXNcMDMwXDAwNCBcMDAzKFx0XDAyMlwwMTNcblwwMDNfMzJcMDMwICBcMDAxKFwwMDVcMDIyXDAxM1xuXDAwM182NFwwMzBAIFwwMDMoXDAwMyIgKwogICAgICAiMlwyMjBcMDAxXG5cMDMyVGVzdENvbmZsaWN0aW5nTWV0aG9kTmFtZXNcMDIyclxuXDAxME92ZXJyIiArCiAgICAgICJpZGVcMDIyMi5pb19wcm90b2NvbF90ZXN0cy5Gb3JiaWRkZW5Xb3Jkc1VuIiArCiAgICAgICJkZXJzY29yZU1lc3NhZ2VcMDMyMi5pb19wcm90b2NvbF90ZXN0cy5Gb3JiIiArCiAgICAgICJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VCMVxuXDAyM2NvbS5nb29nbCIgKwogICAgICAiZS5wcm90b2J1ZkJcMDI3VGVzdEJhZElkZW50aWZpZXJzUHJvdG9cMjEwXDAwMVwwMDEiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQ2xhc3NfIiwgIkRlZmF1bHRJbnN0YW5jZUZvclR5cGVfIiwgIlBhcnNlckZvclR5cGVfIiwgIlNlcmlhbGl6ZWRTaXplXyIsICJBbGxGaWVsZHNfIiwgIkRlc2NyaXB0b3JGb3JUeXBlXyIsICJJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nXyIsICJVbmtub3duRmllbGRzXyIsICJDYWNoZWRTaXplXyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ZvcmJpZGRlbldvcmRzTGVhZGluZ1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDbGFzc18iLCAiRGVmYXVsdEluc3RhbmNlRm9yVHlwZV8iLCAiUGFyc2VyRm9yVHlwZV8iLCAiU2VyaWFsaXplZFNpemVfIiwgIkFsbEZpZWxkc18iLCAiRGVzY3JpcHRvckZvclR5cGVfIiwgIkluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmdfIiwgIkNhY2hlZFNpemVfIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRm9yYmlkZGVuV29yZHNDYW1lbE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkNsYXNzXyIsICJEZWZhdWx0SW5zdGFuY2VGb3JUeXBlXyIsICJTZXJpYWxpemVkU2l6ZV8iLCAiUGFyc2VyRm9yVHlwZV8iLCAiSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZ18iLCAiRGVzY3JpcHRvckZvclR5cGVfIiwgIkFsbEZpZWxkc18iLCAiQ2FjaGVkU2l6ZV8iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXNjcmlwdG9yX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0Rlc2NyaXB0b3JfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGVzY3JpcHRvciIsICJOZXN0ZWREZXNjcmlwdG9yIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9OZXN0ZWREZXNjcmlwdG9yX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVzY3JpcHRvcl9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0Rlc2NyaXB0b3JfTmVzdGVkRGVzY3JpcHRvcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXNjcmlwdG9yX05lc3RlZERlc2NyaXB0b3JfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkRlc2NyaXB0b3IiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19QYXJzZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfUGFyc2VyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1BhcnNlcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUGFyc2VyIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRGVwcmVjYXRlZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19EZXByZWNhdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0RlcHJlY2F0ZWRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZpZWxkMSIsICJGaWVsZDIiLCAiRmllbGQzIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT3ZlcnJpZGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT3ZlcnJpZGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT3ZlcnJpZGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk92ZXJyaWRlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfT2JqZWN0X2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX09iamVjdF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19PYmplY3RfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9iamVjdCIsICJTdHJpbmdPYmplY3QiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19TdHJpbmdfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfU3RyaW5nX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1N0cmluZ19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiU3RyaW5nIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfSW50ZWdlcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg5KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19JbnRlZ2VyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0ludGVnZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkludGVnZXIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Mb25nX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEwKTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Mb25nX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX0xvbmdfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkxvbmciLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19GbG9hdF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRmxvYXRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZsb2F0IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRG91YmxlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEyKTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19Eb3VibGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfRG91YmxlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEb3VibGUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEzKTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkludDMyRmllbGQxIiwgIkVudW1GaWVsZDIiLCAiU3RyaW5nRmllbGQzIiwgIkJ5dGVzRmllbGQ0IiwgIk1lc3NhZ2VGaWVsZDUiLCAiSW50MzJGaWVsZENvdW50MTEiLCAiRW51bUZpZWxkQ291bnQxMiIsICJTdHJpbmdGaWVsZENvdW50MTMiLCAiQnl0ZXNGaWVsZENvdW50MTQiLCAiTWVzc2FnZUZpZWxkQ291bnQxNSIsICJJbnQzMkZpZWxkMjEiLCAiRW51bUZpZWxkMjIiLCAiU3RyaW5nRmllbGQyMyIsICJCeXRlc0ZpZWxkMjQiLCAiTWVzc2FnZUZpZWxkMjUiLCAiSW50MzJGaWVsZExpc3QzMSIsICJGaWVsZE5hbWUzMiIsICJGaWVsZE5hbWUzMyIsICIyQ29uZmxpY3QzNCIsICIyQ29uZmxpY3QzNSIsICJJbnQ2NEZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19Gb3JiaWRkZW5Xb3Jkc1VuZGVyc2NvcmVNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdENvbmZsaWN0aW5nRmllbGROYW1lc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RDb25mbGljdGluZ0ZpZWxkTmFtZXNfRm9yYmlkZGVuV29yZHNVbmRlcnNjb3JlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0Q29uZmxpY3RpbmdGaWVsZE5hbWVzX0ZvcmJpZGRlbldvcmRzVW5kZXJzY29yZU1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDE0KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNYXBGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NYXBGaWVsZF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWFwRmllbGRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX1BhaXJfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfUGFpcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfUGFpcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TWFwRmllbGRfTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RNYXBGaWVsZF9NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX01hcEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfaW9fcHJvdG9jb2xfdGVzdHNfVGVzdE1hcEZpZWxkX01hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX2lvX3Byb3RvY29sX3Rlc3RzX1Rlc3RMZWFkaW5nTnVtYmVyRmllbGRzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDE1KTsKICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TGVhZGluZ051bWJlckZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19pb19wcm90b2NvbF90ZXN0c19UZXN0TGVhZGluZ051bWJlckZpZWxkc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiMzBEYXlJbXByZXNzaW9ucyIsICI2MERheUltcHJlc3Npb25zIiwgIjJVbmRlcnNjb3JlcyIsICIyUmVwZWF0ZWRVbmRlcnNjb3JlcyIsICIzMiIsICI2NCIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEA7XT5W3XKMwB1yjMALgAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9Qcm90bzJUZXN0aW5nLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8yX21lc3NhZ2UucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZzsKCnB1YmxpYyBmaW5hbCBjbGFzcyBQcm90bzJUZXN0aW5nIHsKICBwcml2YXRlIFByb3RvMlRlc3RpbmcoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGREb3VibGUxKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZEZsb2F0Mik7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRJbnQ2NDMpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkVWludDY0NCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRJbnQzMjUpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkRml4ZWQ2NDYpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkRml4ZWQzMjcpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkQm9vbDgpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkU3RyaW5nOSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRNZXNzYWdlMTApOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkQnl0ZXMxMSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRVaW50MzIxMik7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRFbnVtMTMpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkU2ZpeGVkMzIxNCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRTZml4ZWQ2NDE1KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFNpbnQzMjE2KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFNpbnQ2NDE3KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZERvdWJsZUxpc3QxOCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRGbG9hdExpc3QxOSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRJbnQ2NExpc3QyMCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRVaW50NjRMaXN0MjEpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkSW50MzJMaXN0MjIpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkRml4ZWQ2NExpc3QyMyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRGaXhlZDMyTGlzdDI0KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZEJvb2xMaXN0MjUpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkU3RyaW5nTGlzdDI2KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZE1lc3NhZ2VMaXN0MjcpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkQnl0ZXNMaXN0MjgpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkVWludDMyTGlzdDI5KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZEVudW1MaXN0MzApOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkU2ZpeGVkMzJMaXN0MzEpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkU2ZpeGVkNjRMaXN0MzIpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkU2ludDMyTGlzdDMzKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFNpbnQ2NExpc3QzNCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGREb3VibGVMaXN0UGFja2VkMzUpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkRmxvYXRMaXN0UGFja2VkMzYpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkSW50NjRMaXN0UGFja2VkMzcpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZEludDMyTGlzdFBhY2tlZDM5KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDApOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRCb29sTGlzdFBhY2tlZDQyKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0Myk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRFbnVtTGlzdFBhY2tlZDQ0KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0Nyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRTaW50NjRMaXN0UGFja2VkNDgpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmZpZWxkR3JvdXA0OSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuZmllbGRHcm91cExpc3Q1MSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgUHJvdG8yU3BlY2lhbEZpZWxkTmFtZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSByZWd1bGFyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVndWxhck5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlZ3VsYXJOYW1lKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSByZWd1bGFyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlZ3VsYXJOYW1lLgogICAgICovCiAgICBkb3VibGUgZ2V0UmVndWxhck5hbWUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNhY2hlZF9zaXplID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNhY2hlZFNpemUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NhY2hlZFNpemVfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNhY2hlZF9zaXplID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjYWNoZWRTaXplLgogICAgICovCiAgICBpbnQgZ2V0Q2FjaGVkU2l6ZV8oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzZXJpYWxpemVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU2VyaWFsaXplZFNpemVfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2VyaWFsaXplZFNpemUuCiAgICAgKi8KICAgIGxvbmcgZ2V0U2VyaWFsaXplZFNpemVfKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2xhc3MgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NsYXNzXygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNsYXNzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldENsYXNzXygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjbGFzcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Q2xhc3NfQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMlNwZWNpYWxGaWVsZE5hbWV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm90bzJTcGVjaWFsRmllbGROYW1lIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJTcGVjaWFsRmllbGROYW1lKQogICAgICBQcm90bzJTcGVjaWFsRmllbGROYW1lT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQcm90bzJTcGVjaWFsRmllbGROYW1lLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFByb3RvMlNwZWNpYWxGaWVsZE5hbWUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBQcm90bzJTcGVjaWFsRmllbGROYW1lKCkgewogICAgICBjbGFzc19fID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFR1VMQVJfTkFNRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBkb3VibGUgcmVndWxhck5hbWVfID0gMEQ7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSByZWd1bGFyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVndWxhck5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZWd1bGFyTmFtZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgcmVndWxhcl9uYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZWd1bGFyTmFtZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRSZWd1bGFyTmFtZSgpIHsKICAgICAgcmV0dXJuIHJlZ3VsYXJOYW1lXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQUNIRURfU0laRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgY2FjaGVkU2l6ZV9fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgY2FjaGVkX3NpemUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NhY2hlZFNpemVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNhY2hlZF9zaXplID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjYWNoZWRTaXplLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENhY2hlZFNpemVfKCkgewogICAgICByZXR1cm4gY2FjaGVkU2l6ZV9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUklBTElaRURfU0laRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBsb25nIHNlcmlhbGl6ZWRTaXplX18gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgc2VyaWFsaXplZF9zaXplID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNlcmlhbGl6ZWRTaXplIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU2VyaWFsaXplZFNpemVfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2VyaWFsaXplZFNpemUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldFNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgcmV0dXJuIHNlcmlhbGl6ZWRTaXplX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRklFTERfTlVNQkVSID0gNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGNsYXNzX18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNsYXNzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ2xhc3NfKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2xhc3MuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENsYXNzXygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjbGFzc19fOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGNsYXNzX18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjbGFzcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldENsYXNzX0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGNsYXNzX187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGNsYXNzX18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxLCByZWd1bGFyTmFtZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGNhY2hlZFNpemVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMywgc2VyaWFsaXplZFNpemVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA0LCBjbGFzc19fKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoMSwgcmVndWxhck5hbWVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGNhY2hlZFNpemVfXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgzLCBzZXJpYWxpemVkU2l6ZV9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDQsIGNsYXNzX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSkgb2JqOwoKICAgICAgaWYgKGhhc1JlZ3VsYXJOYW1lKCkgIT0gb3RoZXIuaGFzUmVndWxhck5hbWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVndWxhck5hbWUoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0UmVndWxhck5hbWUoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0UmVndWxhck5hbWUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ2FjaGVkU2l6ZV8oKSAhPSBvdGhlci5oYXNDYWNoZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDYWNoZWRTaXplXygpKSB7CiAgICAgICAgaWYgKGdldENhY2hlZFNpemVfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Q2FjaGVkU2l6ZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTZXJpYWxpemVkU2l6ZV8oKSAhPSBvdGhlci5oYXNTZXJpYWxpemVkU2l6ZV8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU2VyaWFsaXplZFNpemVfKCkpIHsKICAgICAgICBpZiAoZ2V0U2VyaWFsaXplZFNpemVfKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0U2VyaWFsaXplZFNpemVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ2xhc3NfKCkgIT0gb3RoZXIuaGFzQ2xhc3NfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0NsYXNzXygpKSB7CiAgICAgICAgaWYgKCFnZXRDbGFzc18oKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENsYXNzXygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1JlZ3VsYXJOYW1lKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRUdVTEFSX05BTUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRSZWd1bGFyTmFtZSgpKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NhY2hlZFNpemVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDQUNIRURfU0laRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2FjaGVkU2l6ZV8oKTsKICAgICAgfQogICAgICBpZiAoaGFzU2VyaWFsaXplZFNpemVfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTRVJJQUxJWkVEX1NJWkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldFNlcmlhbGl6ZWRTaXplXygpKTsKICAgICAgfQogICAgICBpZiAoaGFzQ2xhc3NfKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2xhc3NfKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJTcGVjaWFsRmllbGROYW1lfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMlNwZWNpYWxGaWVsZE5hbWVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJTcGVjaWFsRmllbGROYW1lX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZWd1bGFyTmFtZV8gPSAwRDsKICAgICAgICBjYWNoZWRTaXplX18gPSAwOwogICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSAwTDsKICAgICAgICBjbGFzc19fID0gIiI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZWd1bGFyTmFtZV8gPSByZWd1bGFyTmFtZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2FjaGVkU2l6ZV9fID0gY2FjaGVkU2l6ZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnNlcmlhbGl6ZWRTaXplX18gPSBzZXJpYWxpemVkU2l6ZV9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNsYXNzX18gPSBjbGFzc19fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJTcGVjaWFsRmllbGROYW1lIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNSZWd1bGFyTmFtZSgpKSB7CiAgICAgICAgICBzZXRSZWd1bGFyTmFtZShvdGhlci5nZXRSZWd1bGFyTmFtZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0NhY2hlZFNpemVfKCkpIHsKICAgICAgICAgIHNldENhY2hlZFNpemVfKG90aGVyLmdldENhY2hlZFNpemVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU2VyaWFsaXplZFNpemVfKCkpIHsKICAgICAgICAgIHNldFNlcmlhbGl6ZWRTaXplXyhvdGhlci5nZXRTZXJpYWxpemVkU2l6ZV8oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNDbGFzc18oKSkgewogICAgICAgICAgY2xhc3NfXyA9IG90aGVyLmNsYXNzX187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA5OiB7CiAgICAgICAgICAgICAgICByZWd1bGFyTmFtZV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOQogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGNhY2hlZFNpemVfXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY2xhc3NfXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgZG91YmxlIHJlZ3VsYXJOYW1lXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgcmVndWxhcl9uYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVndWxhck5hbWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZWd1bGFyTmFtZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSByZWd1bGFyX25hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVndWxhck5hbWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVndWxhck5hbWUoKSB7CiAgICAgICAgcmV0dXJuIHJlZ3VsYXJOYW1lXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIHJlZ3VsYXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlZ3VsYXJOYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVndWxhck5hbWUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIHJlZ3VsYXJOYW1lXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIHJlZ3VsYXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlZ3VsYXJOYW1lKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICByZWd1bGFyTmFtZV8gPSAwRDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgY2FjaGVkU2l6ZV9fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNhY2hlZF9zaXplID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2FjaGVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NhY2hlZFNpemVfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgY2FjaGVkX3NpemUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY2FjaGVkU2l6ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDYWNoZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gY2FjaGVkU2l6ZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjYWNoZWRfc2l6ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNhY2hlZFNpemUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDYWNoZWRTaXplXyhpbnQgdmFsdWUpIHsKCiAgICAgICAgY2FjaGVkU2l6ZV9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjYWNoZWRfc2l6ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNhY2hlZFNpemVfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBjYWNoZWRTaXplX18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgc2VyaWFsaXplZFNpemVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBzZXJpYWxpemVkX3NpemUgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzZXJpYWxpemVkU2l6ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkU2l6ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0U2VyaWFsaXplZFNpemVfKCkgewogICAgICAgIHJldHVybiBzZXJpYWxpemVkU2l6ZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBzZXJpYWxpemVkX3NpemUgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzZXJpYWxpemVkU2l6ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNlcmlhbGl6ZWRTaXplXyhsb25nIHZhbHVlKSB7CgogICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgY2xhc3NfXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2xhc3MgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ2xhc3NfKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNsYXNzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q2xhc3NfKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gY2xhc3NfXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGNsYXNzX18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjbGFzcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldENsYXNzX0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gY2xhc3NfXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgY2xhc3NfXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNsYXNzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2xhc3NfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2xhc3NfKCkgewogICAgICAgIGNsYXNzX18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRDbGFzc18oKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBjbGFzcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENsYXNzX0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjbGFzc19fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJTcGVjaWFsRmllbGROYW1lKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yU3BlY2lhbEZpZWxkTmFtZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMlNwZWNpYWxGaWVsZE5hbWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8yU3BlY2lhbEZpZWxkTmFtZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMlNwZWNpYWxGaWVsZE5hbWUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJTcGVjaWFsRmllbGROYW1lPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMlNwZWNpYWxGaWVsZE5hbWU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMlNwZWNpYWxGaWVsZE5hbWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBQcm90bzJNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGREb3VibGUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBmaWVsZF9kb3VibGVfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGUxLgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGREb3VibGUxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZsb2F0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0Mi4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRGbG9hdDIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQ2NDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkSW50NjQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQzLgogICAgICovCiAgICBsb25nIGdldEZpZWxkSW50NjQzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZmllbGRfdWludDY0XzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50NjQ0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFVpbnQ2NDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDQuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjQ0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEludDMyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNS4KICAgICAqLwogICAgaW50IGdldEZpZWxkSW50MzI1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkNjQ2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ2LgogICAgICovCiAgICBsb25nIGdldEZpZWxkRml4ZWQ2NDYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQzMjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRml4ZWQzMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzI3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJvb2w4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w4LgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkQm9vbDgoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFN0cmluZzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU3RyaW5nOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2UxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTEwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWVzc2FnZTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTEwT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzMTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzMTEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyMTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDMyMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyMTIuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMjEyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRFbnVtMTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRW51bTEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtMTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtMTMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDMyMTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzIxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl8xNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzIxNC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkMzIxNCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkNjQxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQ2NDE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDE1LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ZpeGVkNjQxNSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50MzIxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTaW50MzIxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZmllbGRfc2ludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzIxNi4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyMTYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBmaWVsZF9zaW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDY0MTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ludDY0MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0MTcuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZERvdWJsZUxpc3QxOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3QxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3QxOChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3QxOS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3QxOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0MTkoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdDIwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQ2NExpc3QyMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3QyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3QyMChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdDIxLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0MjEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkVWludDY0TGlzdDIxKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAqLwogICAgaW50IGdldEZpZWxkSW50MzJMaXN0MjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0MjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdDIzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3QyNS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3QyNS4KICAgICAqLwogICAgaW50IGdldEZpZWxkQm9vbExpc3QyNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3QyNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTdHJpbmdMaXN0MjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nTGlzdDI2KGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiAKICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEJ5dGVzTGlzdDI4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzTGlzdDI4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXNMaXN0MjgoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0MjkuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFVpbnQzMkxpc3QyOUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3QyOS4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyTGlzdDI5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyTGlzdDI5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyTGlzdDI5KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEVudW1MaXN0MzAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3QzMExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkRW51bUxpc3QzMChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkMzJMaXN0MzEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzEoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzJMaXN0MzMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50NjRMaXN0MzQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDY0TGlzdDM0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdDM0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNpbnQ2NExpc3QzNChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0UGFja2VkMzUuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzNyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3RQYWNrZWQzOS4KICAgICAqLwogICAgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAqLwogICAgaW50IGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDgoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkZ3JvdXA0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRHcm91cDQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZGdyb3VwNDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IGdldEZpZWxkR3JvdXA0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwNDlPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTE+IAogICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RmllbGRHcm91cExpc3Q1MShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkR3JvdXBMaXN0NTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RmllbGRHcm91cExpc3Q1MU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGREb3VibGU1MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGbG9hdDU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZEZsb2F0NTQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkSW50NjQ1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0NTUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDY0NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NTYuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjU3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjU3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQ2NDU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ1OC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjQ1OCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNTkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzI1OSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRCb29sNjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sNjAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU3RyaW5nNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nNjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTYyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWVzc2FnZTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTYyT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMjY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDMyNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyNjUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDY0NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkNjQ2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQ2Ni4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0NjYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ludDMyNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMjY3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNpbnQ2NDY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ludDY0NjgoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkZ3JvdXA2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRHcm91cDY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZGdyb3VwNjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IGdldEZpZWxkR3JvdXA2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwNjlPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWREb3VibGU3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZERvdWJsZTcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRG91YmxlNzEuCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZFJlcXVpcmVkRG91YmxlNzEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZsb2F0IGZpZWxkX3JlcXVpcmVkX2Zsb2F0XzcyID0gNzI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRmxvYXQ3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZsb2F0NzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZmxvYXQgZmllbGRfcmVxdWlyZWRfZmxvYXRfNzIgPSA3Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRmxvYXQ3Mi4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRSZXF1aXJlZEZsb2F0NzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDY0IGZpZWxkX3JlcXVpcmVkX2ludDY0XzczID0gNzM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkSW50NjQ3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50NjQgZmllbGRfcmVxdWlyZWRfaW50NjRfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkSW50NjQ3My4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFJlcXVpcmVkSW50NjQ3MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRVaW50NjQ3NC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFJlcXVpcmVkVWludDY0NzQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGZpZWxkX3JlcXVpcmVkX2ludDMyXzc1ID0gNzU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkSW50MzI3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgZmllbGRfcmVxdWlyZWRfaW50MzJfNzUgPSA3NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkSW50MzI3NS4KICAgICAqLwogICAgaW50IGdldEZpZWxkUmVxdWlyZWRJbnQzMjc1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX2ZpeGVkNjRfNzYgPSA3Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2ID0gNzY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Ni4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9maXhlZDMyXzc3ID0gNzc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZpeGVkMzI3Ny4KICAgICAqLwogICAgaW50IGdldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJvb2wgZmllbGRfcmVxdWlyZWRfYm9vbF83OCA9IDc4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEJvb2w3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEJvb2w3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBib29sIGZpZWxkX3JlcXVpcmVkX2Jvb2xfNzggPSA3ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkQm9vbDc4LgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkUmVxdWlyZWRCb29sNzgoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzkgPSA3OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTdHJpbmc3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzkgPSA3OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU3RyaW5nNzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRSZXF1aXJlZFN0cmluZzc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzkgPSA3OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRSZXF1aXJlZFN0cmluZzc5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRNZXNzYWdlODAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyBmaWVsZF9yZXF1aXJlZF9ieXRlc184MSA9IDgxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEJ5dGVzODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEJ5dGVzODEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQzMjgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkVWludDMyODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRVaW50MzI4Mi4KICAgICAqLwogICAgaW50IGdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRFbnVtODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRW51bTgzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkUmVxdWlyZWRFbnVtODMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX3NmaXhlZDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkMzIgZmllbGRfcmVxdWlyZWRfc2ZpeGVkMzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NC4KICAgICAqLwogICAgaW50IGdldEZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX3NmaXhlZDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODUuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQzMiBmaWVsZF9yZXF1aXJlZF9zaW50MzJfODYgPSA4Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTaW50MzI4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQzMiBmaWVsZF9yZXF1aXJlZF9zaW50MzJfODYgPSA4Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ludDMyODYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFJlcXVpcmVkU2ludDMyODYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTaW50NjQ4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ludDY0ODcuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkcmVxdWlyZWRncm91cDg4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZHJlcXVpcmVkZ3JvdXA4OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIoKTsKCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RPbmVvZkNhc2UgZ2V0VGVzdE9uZW9mQ2FzZSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvMk1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UpCiAgICAgIFByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvMk1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUHJvdG8yTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvMk1lc3NhZ2UoKSB7CiAgICAgIGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgICAgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgZmllbGRFbnVtMTNfID0gMDsKICAgICAgZmllbGREb3VibGVMaXN0MThfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZEdyb3VwTGlzdDUxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9ICIiOwogICAgICBmaWVsZFJlcXVpcmVkQnl0ZXM4MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIGZpZWxkUmVxdWlyZWRFbnVtODNfID0gMDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBQcm90bzJNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBUZXN0RW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlpFUk8gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFpFUk8oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5PTkUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIE9ORSgxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRXTyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgVFdPKDIpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWkVST19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5PTkUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORV9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5UV08gPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRXT19WQUxVRSA9IDI7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFpFUk87CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBPTkU7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBUV087CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIFRlc3RFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBUZXN0RW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVGVzdEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgVGVzdEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSkKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEZpZWxkR3JvdXA0OU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0ZpZWxkSW50MzI1MCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1MC4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZEludDMyNTAoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkR3JvdXA0OSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5KQogICAgICAgIEZpZWxkR3JvdXA0OU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIEZpZWxkR3JvdXA0OS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIEZpZWxkR3JvdXA0OShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIEZpZWxkR3JvdXA0OSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBGaWVsZEdyb3VwNDkoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA0OV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyXzUwX0ZJRUxEX05VTUJFUiA9IDUwOwogICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTBfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUwKCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyNTBfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNTAsIGZpZWxkSW50MzI1MF8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg1MCwgZmllbGRJbnQzMjUwXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5KSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSkgb2JqOwoKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjUwKCkgIT0gb3RoZXIuaGFzRmllbGRJbnQzMjUwKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjUwKCkpIHsKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyNTAoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI1MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjUwKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzUwX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzI1MCgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDl9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSkKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5T3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNDlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGZpZWxkSW50MzI1MF8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cDQ5X2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IGJ1aWxkKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyNTBfID0gZmllbGRJbnQzMjUwXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5KSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5KW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkSW50MzI1MCgpKSB7CiAgICAgICAgICAgIHNldEZpZWxkSW50MzI1MChvdGhlci5nZXRGaWVsZEludDMyNTAoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDQwMDogewogICAgICAgICAgICAgICAgICBmaWVsZEludDMyNTBfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTBfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUwLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1MCgpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEludDMyNTBfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI1MCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzI1MChpbnQgdmFsdWUpIHsKCiAgICAgICAgICBmaWVsZEludDMyNTBfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyNTAoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBmaWVsZEludDMyNTBfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5KQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5KQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA0OT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZpZWxkR3JvdXA0OT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBGaWVsZEdyb3VwNDkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwNDk+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwNDk+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUyKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUyLgogICAgICAgKi8KICAgICAgaW50IGdldEZpZWxkSW50MzI1MigpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkR3JvdXBMaXN0NTEgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEpCiAgICAgICAgRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIEZpZWxkR3JvdXBMaXN0NTEubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBGaWVsZEdyb3VwTGlzdDUxKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgRmllbGRHcm91cExpc3Q1MSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBGaWVsZEdyb3VwTGlzdDUxKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cExpc3Q1MV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNTJfRklFTERfTlVNQkVSID0gNTI7CiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1Ml8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Mi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTIoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI1Ml87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1MiwgZmllbGRJbnQzMjUyXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUyLCBmaWVsZEludDMyNTJfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxKSBvYmo7CgogICAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyNTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSkgewogICAgICAgICAgaWYgKGdldEZpZWxkSW50MzI1MigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjUyKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfNTJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMjUyKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxKQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cExpc3Q1MV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgZmllbGRJbnQzMjUyXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIGJ1aWxkKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI1Ml8gPSBmaWVsZEludDMyNTJfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkSW50MzI1MigpKSB7CiAgICAgICAgICAgIHNldEZpZWxkSW50MzI1MihvdGhlci5nZXRGaWVsZEludDMyNTIoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDQxNjogewogICAgICAgICAgICAgICAgICBmaWVsZEludDMyNTJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE2CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTJfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MigpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUyLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1MigpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEludDMyNTJfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI1MiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzI1MihpbnQgdmFsdWUpIHsKCiAgICAgICAgICBmaWVsZEludDMyNTJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyNTIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBmaWVsZEludDMyNTJfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cExpc3Q1MT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZpZWxkR3JvdXBMaXN0NTE+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRmllbGRHcm91cExpc3Q1MSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXBMaXN0NTE+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwTGlzdDUxPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgRmllbGRHcm91cDY5T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjcwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjcwKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl83MCA9IDcwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjcwLgogICAgICAgKi8KICAgICAgaW50IGdldEZpZWxkSW50MzI3MCgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjl9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRHcm91cDY5IGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpCiAgICAgICAgRmllbGRHcm91cDY5T3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgRmllbGRHcm91cDY5Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgRmllbGRHcm91cDY5KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgRmllbGRHcm91cDY5KCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IEZpZWxkR3JvdXA2OSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA2OV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cDY5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNzBfRklFTERfTlVNQkVSID0gNzA7CiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI3MF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjcwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjcwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI3MC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNzAoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI3MF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig3MCwgZmllbGRJbnQzMjcwXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDcwLCBmaWVsZEludDMyNzBfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KSBvYmo7CgogICAgICAgIGlmIChoYXNGaWVsZEludDMyNzAoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyNzAoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNGaWVsZEludDMyNzAoKSkgewogICAgICAgICAgaWYgKGdldEZpZWxkSW50MzI3MCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjcwKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNGaWVsZEludDMyNzAoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfNzBfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMjcwKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjlPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA2OV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA2OV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5Lm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgZmllbGRJbnQzMjcwXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNjlfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgYnVpbGQoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI3MF8gPSBmaWVsZEludDMyNzBfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRJbnQzMjcwKCkpIHsKICAgICAgICAgICAgc2V0RmllbGRJbnQzMjcwKG90aGVyLmdldEZpZWxkSW50MzI3MCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNTYwOiB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzI3MF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA1NjAKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI3MF8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjcwIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjcwKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl83MCA9IDcwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNzAuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjcwKCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI3MF87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjcwIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjcwKGludCB2YWx1ZSkgewoKICAgICAgICAgIGZpZWxkSW50MzI3MF8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI3MCgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGZpZWxkSW50MzI3MF8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cDY5PgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RmllbGRHcm91cDY5PigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEZpZWxkR3JvdXA2OSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA2OT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA2OT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgUmVxdWlyZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1ZhbHVlKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIGludCBnZXRWYWx1ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UpCiAgICAgICAgUmVxdWlyZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgUmVxdWlyZWROZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgUmVxdWlyZWROZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgUmVxdWlyZWROZXN0ZWRNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IFJlcXVpcmVkTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX1JlcXVpcmVkTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfUmVxdWlyZWROZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCB2YWx1ZV8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCB2YWx1ZV8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKGhhc1ZhbHVlKCkgIT0gb3RoZXIuaGFzVmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgICBpZiAoZ2V0VmFsdWUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldFZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRWYWx1ZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LnZhbHVlXyA9IHZhbHVlXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1ZhbHVlKCkpIHsKICAgICAgICAgICAgc2V0VmFsdWUob3RoZXIuZ2V0VmFsdWUoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgdmFsdWVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKGludCB2YWx1ZSkgewoKICAgICAgICAgIHZhbHVlXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJWYWx1ZSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXF1aXJlZE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZXF1aXJlZE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVxdWlyZWROZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVxdWlyZWROZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBGaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjg5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjg5KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl84OSA9IDg5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjg5LgogICAgICAgKi8KICAgICAgaW50IGdldEZpZWxkSW50MzI4OSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZFJlcXVpcmVkR3JvdXA4OCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODgpCiAgICAgICAgRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBGaWVsZFJlcXVpcmVkR3JvdXA4OC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIEZpZWxkUmVxdWlyZWRHcm91cDg4KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgRmllbGRSZXF1aXJlZEdyb3VwODgoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgRmllbGRSZXF1aXJlZEdyb3VwODgoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZFJlcXVpcmVkR3JvdXA4OF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRSZXF1aXJlZEdyb3VwODhfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfODlfRklFTERfTlVNQkVSID0gODk7CiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI4OV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjg5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjg5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI4OS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyODkoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI4OV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig4OSwgZmllbGRJbnQzMjg5Xyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDg5LCBmaWVsZEludDMyODlfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4KSBvYmo7CgogICAgICAgIGlmIChoYXNGaWVsZEludDMyODkoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyODkoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNGaWVsZEludDMyODkoKSkgewogICAgICAgICAgaWYgKGdldEZpZWxkSW50MzI4OSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjg5KCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNGaWVsZEludDMyODkoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfODlfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMjg5KCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODh9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4KQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRSZXF1aXJlZEdyb3VwODhfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZFJlcXVpcmVkR3JvdXA4OF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4Lm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgZmllbGRJbnQzMjg5XyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZFJlcXVpcmVkR3JvdXA4OF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI4OV8gPSBmaWVsZEludDMyODlfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4KW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEludDMyODkoKSkgewogICAgICAgICAgICBzZXRGaWVsZEludDMyODkob3RoZXIuZ2V0RmllbGRJbnQzMjg5KCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA3MTI6IHsKICAgICAgICAgICAgICAgICAgZmllbGRJbnQzMjg5XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDcxMgogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMjg5XyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyODkgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyODkoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzg5ID0gODk7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI4OS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyODkoKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRJbnQzMjg5XzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyODkgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyODkoaW50IHZhbHVlKSB7CgogICAgICAgICAgZmllbGRJbnQzMjg5XyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMjg5KCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgZmllbGRJbnQzMjg5XyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4KQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODgpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODgoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRSZXF1aXJlZEdyb3VwODg+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGaWVsZFJlcXVpcmVkR3JvdXA4OD4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBGaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkUmVxdWlyZWRHcm91cDg4PiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRSZXF1aXJlZEdyb3VwODg+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgcHJpdmF0ZSBpbnQgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgdGVzdE9uZW9mXzsKICAgIHB1YmxpYyBlbnVtIFRlc3RPbmVvZkNhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgRklFTERfRE9VQkxFXzUzKDUzKSwKICAgICAgRklFTERfRkxPQVRfNTQoNTQpLAogICAgICBGSUVMRF9JTlQ2NF81NSg1NSksCiAgICAgIEZJRUxEX1VJTlQ2NF81Nig1NiksCiAgICAgIEZJRUxEX0lOVDMyXzU3KDU3KSwKICAgICAgRklFTERfRklYRUQ2NF81OCg1OCksCiAgICAgIEZJRUxEX0ZJWEVEMzJfNTkoNTkpLAogICAgICBGSUVMRF9CT09MXzYwKDYwKSwKICAgICAgRklFTERfU1RSSU5HXzYxKDYxKSwKICAgICAgRklFTERfTUVTU0FHRV82Mig2MiksCiAgICAgIEZJRUxEX0JZVEVTXzYzKDYzKSwKICAgICAgRklFTERfVUlOVDMyXzY0KDY0KSwKICAgICAgRklFTERfU0ZJWEVEMzJfNjUoNjUpLAogICAgICBGSUVMRF9TRklYRUQ2NF82Nig2NiksCiAgICAgIEZJRUxEX1NJTlQzMl82Nyg2NyksCiAgICAgIEZJRUxEX1NJTlQ2NF82OCg2OCksCiAgICAgIEZJRUxER1JPVVA2OSg2OSksCiAgICAgIFRFU1RPTkVPRl9OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBUZXN0T25lb2ZDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdE9uZW9mQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIFRlc3RPbmVvZkNhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgNTM6IHJldHVybiBGSUVMRF9ET1VCTEVfNTM7CiAgICAgICAgICBjYXNlIDU0OiByZXR1cm4gRklFTERfRkxPQVRfNTQ7CiAgICAgICAgICBjYXNlIDU1OiByZXR1cm4gRklFTERfSU5UNjRfNTU7CiAgICAgICAgICBjYXNlIDU2OiByZXR1cm4gRklFTERfVUlOVDY0XzU2OwogICAgICAgICAgY2FzZSA1NzogcmV0dXJuIEZJRUxEX0lOVDMyXzU3OwogICAgICAgICAgY2FzZSA1ODogcmV0dXJuIEZJRUxEX0ZJWEVENjRfNTg7CiAgICAgICAgICBjYXNlIDU5OiByZXR1cm4gRklFTERfRklYRUQzMl81OTsKICAgICAgICAgIGNhc2UgNjA6IHJldHVybiBGSUVMRF9CT09MXzYwOwogICAgICAgICAgY2FzZSA2MTogcmV0dXJuIEZJRUxEX1NUUklOR182MTsKICAgICAgICAgIGNhc2UgNjI6IHJldHVybiBGSUVMRF9NRVNTQUdFXzYyOwogICAgICAgICAgY2FzZSA2MzogcmV0dXJuIEZJRUxEX0JZVEVTXzYzOwogICAgICAgICAgY2FzZSA2NDogcmV0dXJuIEZJRUxEX1VJTlQzMl82NDsKICAgICAgICAgIGNhc2UgNjU6IHJldHVybiBGSUVMRF9TRklYRUQzMl82NTsKICAgICAgICAgIGNhc2UgNjY6IHJldHVybiBGSUVMRF9TRklYRUQ2NF82NjsKICAgICAgICAgIGNhc2UgNjc6IHJldHVybiBGSUVMRF9TSU5UMzJfNjc7CiAgICAgICAgICBjYXNlIDY4OiByZXR1cm4gRklFTERfU0lOVDY0XzY4OwogICAgICAgICAgY2FzZSA2OTogcmV0dXJuIEZJRUxER1JPVVA2OTsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFRFU1RPTkVPRl9OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBUZXN0T25lb2ZDYXNlCiAgICBnZXRUZXN0T25lb2ZDYXNlKCkgewogICAgICByZXR1cm4gVGVzdE9uZW9mQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFXzFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgZG91YmxlIGZpZWxkRG91YmxlMV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRG91YmxlMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTEoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZTFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgZmxvYXQgZmllbGRGbG9hdDJfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZpZWxkX2Zsb2F0XzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZsb2F0MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXQyKCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdDJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0XzNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgbG9uZyBmaWVsZEludDY0M18gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0MygpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjQzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UNjRfNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkVWludDY0NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZmllbGRfdWludDY0XzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjQ0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjQ0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81X0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIGludCBmaWVsZEludDMyNV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyNV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF82X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIGxvbmcgZmllbGRGaXhlZDY0Nl8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBmaWVsZF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDY0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQ2NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBmaWVsZF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NDYoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjQ2XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyXzdfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgaW50IGZpZWxkRml4ZWQzMjdfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDMyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQzMjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyNygpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMjdfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfOF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBib29sZWFuIGZpZWxkQm9vbDhfID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQm9vbDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJvb2w4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2w4KCkgewogICAgICByZXR1cm4gZmllbGRCb29sOF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU1RSSU5HXzlfRklFTERfTlVNQkVSID0gOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU3RyaW5nOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgZmllbGRTdHJpbmc5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGZpZWxkU3RyaW5nOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFXzEwX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGZpZWxkTWVzc2FnZTEwXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2UxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZE1lc3NhZ2UxMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxME9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkTWVzc2FnZTEwXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU18xMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGZpZWxkQnl0ZXMxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzMTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzMTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCkgewogICAgICByZXR1cm4gZmllbGRCeXRlczExXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIGludCBmaWVsZFVpbnQzMjEyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyMTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQzMjEyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMjEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyMTIoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMjEyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9FTlVNXzEzX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgcHJpdmF0ZSBpbnQgZmllbGRFbnVtMTNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRW51bTEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEVudW0xMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bTEzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkRW51bTEzKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkRW51bTEzXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl8xNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkMzIxNF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl8xNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjE0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMjE0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzIxNCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzIxNF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfMTVfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIGxvbmcgZmllbGRTZml4ZWQ2NDE1XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDE1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQ2NDE1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgaW50IGZpZWxkU2ludDMyMTZfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50MzIxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDMyMTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyMTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzIxNigpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyMTZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF8xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50NjQxNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0MTdfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3QxOF8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGREb3VibGVMaXN0MThDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3QxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0MTgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF9MSVNUXzE5X0ZJRUxEX05VTUJFUiA9IDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IGZpZWxkRmxvYXRMaXN0MTlfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0MTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF9MSVNUXzIwX0ZJRUxEX05VTUJFUiA9IDIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3QyMF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3QyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3QyMENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0MjAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfMjFfRklFTERfTlVNQkVSID0gMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFVpbnQ2NExpc3QyMV8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQ2NExpc3QyMUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0TGlzdDIxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfTElTVF8yMl9GSUVMRF9OVU1CRVIgPSAyMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRJbnQzMkxpc3QyMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdDIyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3QyMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0MjJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF9MSVNUXzIzX0ZJRUxEX05VTUJFUiA9IDIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRGaXhlZDY0TGlzdDIzXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdDIzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdDIzXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyX0xJU1RfMjRfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkRml4ZWQzMkxpc3QyNF8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0MjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF9MSVNUXzI1X0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdDI1XyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3QyNV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0MjUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdDI1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdDI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1Xy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TVFJJTkdfTElTVF8yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFN0cmluZ0xpc3QyNi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFX0xJU1RfMjdfRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNZXNzYWdlTGlzdDI3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU19MSVNUXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRCeXRlc0xpc3QyOF8gPQogICAgICAgIGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXNMaXN0MjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXNMaXN0MjgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9MSVNUXzI5X0ZJRUxEX05VTUJFUiA9IDI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFVpbnQzMkxpc3QyOV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0MjkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRU5VTV9MSVNUXzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0MzBfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3QzMExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPihmaWVsZEVudW1MaXN0MzBfLCBmaWVsZEVudW1MaXN0MzBfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0MzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkRW51bUxpc3QzMChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfLmNvbnZlcnQoZmllbGRFbnVtTGlzdDMwXy5nZXQoaW5kZXgpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl9MSVNUXzMxX0ZJRUxEX05VTUJFUiA9IDMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF9MSVNUXzMyX0ZJRUxEX05VTUJFUiA9IDMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3QzMl8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkNjRMaXN0MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDMyX0xJU1RfMzNfRklFTERfTlVNQkVSID0gMzM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ludDMyTGlzdDMzXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50MzJMaXN0MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50MzJMaXN0MzMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM18uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UNjRfTElTVF8zNF9GSUVMRF9OVU1CRVIgPSAzNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkU2ludDY0TGlzdDM0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDY0TGlzdDM0Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjRMaXN0MzQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NExpc3QzNChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdDM0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9ET1VCTEVfTElTVF9QQUNLRURfMzVfRklFTERfTlVNQkVSID0gMzU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9CiAgICAgICAgZW1wdHlEb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5nZXREb3VibGUoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGREb3VibGVMaXN0UGFja2VkMzVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfTElTVF9QQUNLRURfMzZfRklFTERfTlVNQkVSID0gMzY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRGbG9hdExpc3RQYWNrZWQzNk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF9MSVNUX1BBQ0tFRF8zN19GSUVMRF9OVU1CRVIgPSAzNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzNyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQ2NExpc3RQYWNrZWQzN01lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UNjRfTElTVF9QQUNLRURfMzhfRklFTERfTlVNQkVSID0gMzg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl9MSVNUX1BBQ0tFRF8zOV9GSUVMRF9OVU1CRVIgPSAzOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3RQYWNrZWQzOS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEludDMyTGlzdFBhY2tlZDM5TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfTElTVF9QQUNLRURfNDBfRklFTERfTlVNQkVSID0gNDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVEMzJfTElTVF9QQUNLRURfNDFfRklFTERfTlVNQkVSID0gNDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF9MSVNUX1BBQ0tFRF80Ml9GSUVMRF9OVU1CRVIgPSA0MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0UGFja2VkNDJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEJvb2xMaXN0UGFja2VkNDJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDMyX0xJU1RfUEFDS0VEXzQzX0ZJRUxEX05VTUJFUiA9IDQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9FTlVNX0xJU1RfUEFDS0VEXzQ0X0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0UGFja2VkNDRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPihmaWVsZEVudW1MaXN0UGFja2VkNDRfLCBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF9jb252ZXJ0ZXJfLmNvbnZlcnQoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkRW51bUxpc3RQYWNrZWQ0NE1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfTElTVF9QQUNLRURfNDVfRklFTERfTlVNQkVSID0gNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF9MSVNUX1BBQ0tFRF80Nl9GSUVMRF9OVU1CRVIgPSA0NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UMzJfTElTVF9QQUNLRURfNDdfRklFTERfTlVNQkVSID0gNDc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50MzJMaXN0UGFja2VkNDcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF9MSVNUX1BBQ0tFRF80OF9GSUVMRF9OVU1CRVIgPSA0ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0UGFja2VkNDhfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxER1JPVVA0OV9GSUVMRF9OVU1CRVIgPSA0OTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgZmllbGRHcm91cDQ5XzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRncm91cDQ5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRHcm91cDQ5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZGdyb3VwNDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSBnZXRGaWVsZEdyb3VwNDkoKSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkR3JvdXA0OV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwNDlPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkR3JvdXA0OV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERHUk9VUExJU1Q1MV9GSUVMRF9OVU1CRVIgPSA1MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTE+IGZpZWxkR3JvdXBMaXN0NTFfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MT4gZ2V0RmllbGRHcm91cExpc3Q1MUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEdyb3VwTGlzdDUxQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIGdldEZpZWxkR3JvdXBMaXN0NTEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRHcm91cExpc3Q1MV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9ET1VCTEVfNTNfRklFTERfTlVNQkVSID0gNTM7CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlNTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTUzKCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlNTMoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkRvdWJsZSkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfNTRfRklFTERfTlVNQkVSID0gNTQ7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZsb2F0NTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZsb2F0NTQoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0NTQoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwRjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF81NV9GSUVMRF9OVU1CRVIgPSA1NTsKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50NjQ1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQ1NSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDU1KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UNjRfNTZfRklFTERfTlVNQkVSID0gNTY7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQ2NDU2KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTY7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDU2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NDU2KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81N19GSUVMRF9OVU1CRVIgPSA1NzsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1NygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTcoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF81OF9GSUVMRF9OVU1CRVIgPSA1ODsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzU4ID0gNTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkNjQ1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQ2NDU4KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTg7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDU4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl81OV9GSUVMRF9OVU1CRVIgPSA1OTsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQzMjU5KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjU5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMjU5KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTkpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfNjBfRklFTERfTlVNQkVSID0gNjA7CiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sNjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJvb2w2MCgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYwOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sNjAoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NUUklOR182MV9GSUVMRF9OVU1CRVIgPSA2MTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTdHJpbmc2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU3RyaW5nNjEoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nNjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIHJlZiA9IHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkpIHsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZzYxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIHJlZiA9IHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01FU1NBR0VfNjJfRklFTERfTlVNQkVSID0gNjI7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1lc3NhZ2U2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTYyKCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRNZXNzYWdlNjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWVzc2FnZTYyKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlNjJPckJ1aWxkZXIoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQllURVNfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzNjMoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczYzKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDMyNjQoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzI2NCgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl82NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkMzI2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzI2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyNjUoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDY0NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ZpeGVkNjQ2NigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY2KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDMyXzY3X0ZJRUxEX05VTUJFUiA9IDY3OwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQzMjY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzI2NygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzI2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMjY3KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF82OF9GSUVMRF9OVU1CRVIgPSA2ODsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQ2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0NjgoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2ODsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0NjgoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBMOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxER1JPVVA2OV9GSUVMRF9OVU1CRVIgPSA2OTsKICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRncm91cDY5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRHcm91cDY5KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZGdyb3VwNjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSBnZXRGaWVsZEdyb3VwNjkoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5T3JCdWlsZGVyIGdldEZpZWxkR3JvdXA2OU9yQnVpbGRlcigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX0RPVUJMRV83MV9GSUVMRF9OVU1CRVIgPSA3MTsKICAgIHByaXZhdGUgZG91YmxlIGZpZWxkUmVxdWlyZWREb3VibGU3MV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIGZpZWxkX3JlcXVpcmVkX2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZERvdWJsZTcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZERvdWJsZTcxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRG91YmxlNzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRSZXF1aXJlZERvdWJsZTcxKCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZERvdWJsZTcxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9GTE9BVF83Ml9GSUVMRF9OVU1CRVIgPSA3MjsKICAgIHByaXZhdGUgZmxvYXQgZmllbGRSZXF1aXJlZEZsb2F0NzJfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZsb2F0IGZpZWxkX3JlcXVpcmVkX2Zsb2F0XzcyID0gNzI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRmxvYXQ3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZsb2F0IGZpZWxkX3JlcXVpcmVkX2Zsb2F0XzcyID0gNzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZsb2F0NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRGbG9hdDcyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9JTlQ2NF83M19GSUVMRF9OVU1CRVIgPSA3MzsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFJlcXVpcmVkSW50NjQ3M18gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50NjQgZmllbGRfcmVxdWlyZWRfaW50NjRfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRJbnQ2NDczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50NjQgZmllbGRfcmVxdWlyZWRfaW50NjRfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkSW50NjQ3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRSZXF1aXJlZEludDY0NzMoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkSW50NjQ3M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfVUlOVDY0Xzc0X0ZJRUxEX05VTUJFUiA9IDc0OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQ2NCBmaWVsZF9yZXF1aXJlZF91aW50NjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkVWludDY0NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfSU5UMzJfNzVfRklFTERfTlVNQkVSID0gNzU7CiAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkSW50MzI3NV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBmaWVsZF9yZXF1aXJlZF9pbnQzMl83NSA9IDc1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEludDMyNzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBmaWVsZF9yZXF1aXJlZF9pbnQzMl83NSA9IDc1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRJbnQzMjc1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRJbnQzMjc1KCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEludDMyNzVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX0ZJWEVENjRfNzZfRklFTERfTlVNQkVSID0gNzY7CiAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2ID0gNzY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX2ZpeGVkNjRfNzYgPSA3Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfRklYRUQzMl83N19GSUVMRF9OVU1CRVIgPSA3NzsKICAgIHByaXZhdGUgaW50IGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9maXhlZDMyXzc3ID0gNzc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9CT09MXzc4X0ZJRUxEX05VTUJFUiA9IDc4OwogICAgcHJpdmF0ZSBib29sZWFuIGZpZWxkUmVxdWlyZWRCb29sNzhfID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJvb2wgZmllbGRfcmVxdWlyZWRfYm9vbF83OCA9IDc4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEJvb2w3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYm9vbCBmaWVsZF9yZXF1aXJlZF9ib29sXzc4ID0gNzg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEJvb2w3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRSZXF1aXJlZEJvb2w3OCgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRCb29sNzhfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX1NUUklOR183OV9GSUVMRF9OVU1CRVIgPSA3OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFN0cmluZzc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzkgPSA3OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU3RyaW5nNzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkUmVxdWlyZWRTdHJpbmc3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkUmVxdWlyZWRTdHJpbmc3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9NRVNTQUdFXzgwX0ZJRUxEX05VTUJFUiA9IDgwOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfQllURVNfODFfRklFTERfTlVNQkVSID0gODE7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBmaWVsZFJlcXVpcmVkQnl0ZXM4MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkQnl0ZXM4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEJ5dGVzODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRSZXF1aXJlZEJ5dGVzODEoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkQnl0ZXM4MV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfVUlOVDMyXzgyX0ZJRUxEX05VTUJFUiA9IDgyOwogICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZFVpbnQzMjgyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQzMiBmaWVsZF9yZXF1aXJlZF91aW50MzJfODIgPSA4Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRVaW50MzI4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRVaW50MzI4MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50MzIgZmllbGRfcmVxdWlyZWRfdWludDMyXzgyID0gODI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFVpbnQzMjgyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfRU5VTV84M19GSUVMRF9OVU1CRVIgPSA4MzsKICAgIHByaXZhdGUgaW50IGZpZWxkUmVxdWlyZWRFbnVtODNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRFbnVtODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRW51bTgzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkUmVxdWlyZWRFbnVtODMoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRSZXF1aXJlZEVudW04M18pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8gOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfU0ZJWEVEMzJfODRfRklFTERfTlVNQkVSID0gODQ7CiAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9zZml4ZWQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNmaXhlZDMyODQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9zZml4ZWQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX1NGSVhFRDY0Xzg1X0ZJRUxEX05VTUJFUiA9IDg1OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9TSU5UMzJfODZfRklFTERfTlVNQkVSID0gODY7CiAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkU2ludDMyODZfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDMyIGZpZWxkX3JlcXVpcmVkX3NpbnQzMl84NiA9IDg2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNpbnQzMjg2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQzMiBmaWVsZF9yZXF1aXJlZF9zaW50MzJfODYgPSA4Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ludDMyODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZFNpbnQzMjg2KCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFNpbnQzMjg2XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9TSU5UNjRfODdfRklFTERfTlVNQkVSID0gODc7CiAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZFNpbnQ2NDg3XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50NjQgZmllbGRfcmVxdWlyZWRfc2ludDY0Xzg3ID0gODc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkU2ludDY0ODcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDY0IGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84NyA9IDg3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTaW50NjQ4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFNpbnQ2NDg3XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRFJFUVVJUkVER1JPVVA4OF9GSUVMRF9OVU1CRVIgPSA4ODsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRyZXF1aXJlZGdyb3VwODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZHJlcXVpcmVkZ3JvdXA4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggZ2V0RmllbGRSZXF1aXJlZEdyb3VwODgoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODguZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODguZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEZsb2F0NzIoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRVaW50MzI4MigpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEdyb3VwODgoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2UxMCgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZE1lc3NhZ2UxMCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdDb3VudCgpOyBpKyspIHsKICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZUxpc3QyNyhpKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2U2MigpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZE1lc3NhZ2U2MigpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoMSwgZmllbGREb3VibGUxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMiwgZmllbGRGbG9hdDJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgzLCBmaWVsZEludDY0M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCBmaWVsZFVpbnQ2NDRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1LCBmaWVsZEludDMyNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoNiwgZmllbGRGaXhlZDY0Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoNywgZmllbGRGaXhlZDMyN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woOCwgZmllbGRCb29sOF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgOSwgZmllbGRTdHJpbmc5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMCwgZ2V0RmllbGRNZXNzYWdlMTAoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMTEsIGZpZWxkQnl0ZXMxMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigxMiwgZmllbGRVaW50MzIxMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTMsIGZpZWxkRW51bTEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoMTQsIGZpZWxkU2ZpeGVkMzIxNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDE1LCBmaWVsZFNmaXhlZDY0MTVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoMTYsIGZpZWxkU2ludDMyMTZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoMTcsIGZpZWxkU2ludDY0MTdfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRG91YmxlTGlzdDE4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxOCwgZmllbGREb3VibGVMaXN0MThfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZsb2F0TGlzdDE5Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDE5LCBmaWVsZEZsb2F0TGlzdDE5Xy5nZXRGbG9hdChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDY0TGlzdDIwXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIwLCBmaWVsZEludDY0TGlzdDIwXy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCgyMSwgZmllbGRVaW50NjRMaXN0MjFfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyMiwgZmllbGRJbnQzMkxpc3QyMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRml4ZWQ2NExpc3QyM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDIzLCBmaWVsZEZpeGVkNjRMaXN0MjNfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDMyTGlzdDI0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoMjQsIGZpZWxkRml4ZWQzMkxpc3QyNF8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkQm9vbExpc3QyNV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDI1LCBmaWVsZEJvb2xMaXN0MjVfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNiwgZmllbGRTdHJpbmdMaXN0MjZfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyNywgZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygyOCwgZmllbGRCeXRlc0xpc3QyOF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDMyTGlzdDI5Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigyOSwgZmllbGRVaW50MzJMaXN0MjlfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEVudW1MaXN0MzBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgzMCwgZmllbGRFbnVtTGlzdDMwXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTZml4ZWQzMkxpc3QzMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMigzMSwgZmllbGRTZml4ZWQzMkxpc3QzMV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkNjRMaXN0MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMzIsIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDMzLCBmaWVsZFNpbnQzMkxpc3QzM18uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdDM0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgzNCwgZmllbGRTaW50NjRMaXN0MzRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjgyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZERvdWJsZUxpc3RQYWNrZWQzNU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlTm9UYWcoZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI5MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRGbG9hdExpc3RQYWNrZWQzNk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdE5vVGFnKGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjk4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEludDY0TGlzdFBhY2tlZDM3TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMDYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMxNCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRJbnQzMkxpc3RQYWNrZWQzOU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzIyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0Tm9UYWcoZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzM4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEJvb2xMaXN0UGFja2VkNDJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcoZmllbGRCb29sTGlzdFBhY2tlZDQyXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM0Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM1NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRFbnVtTGlzdFBhY2tlZDQ0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEVudW1MaXN0UGFja2VkNDRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzYyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyTm9UYWcoZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzcwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcoZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzJOb1RhZyhmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM4Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRTaW50NjRMaXN0UGFja2VkNDhNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NE5vVGFnKGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg0OSwgZ2V0RmllbGRHcm91cDQ5KCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRHcm91cExpc3Q1MV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg1MSwgZmllbGRHcm91cExpc3Q1MV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTMpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoCiAgICAgICAgICAgIDUzLCAoZG91YmxlKSgoamF2YS5sYW5nLkRvdWJsZSkgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KAogICAgICAgICAgICA1NCwgKGZsb2F0KSgoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoCiAgICAgICAgICAgIDU1LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KAogICAgICAgICAgICA1NiwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKAogICAgICAgICAgICA1NywgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCgKICAgICAgICAgICAgNTgsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKAogICAgICAgICAgICA1OSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgKICAgICAgICAgICAgNjAsIChib29sZWFuKSgoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDYxLCB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDYyLCAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYzKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoCiAgICAgICAgICAgIDYzLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoCiAgICAgICAgICAgIDY0LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMigKICAgICAgICAgICAgNjUsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KAogICAgICAgICAgICA2NiwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMigKICAgICAgICAgICAgNjcsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgKICAgICAgICAgICAgNjgsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjkpIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg2OSwgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KSB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoNzEsIGZpZWxkUmVxdWlyZWREb3VibGU3MV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDcyLCBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDczLCBmaWVsZFJlcXVpcmVkSW50NjQ3M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg3NCwgZmllbGRSZXF1aXJlZFVpbnQ2NDc0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNzUsIGZpZWxkUmVxdWlyZWRJbnQzMjc1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg3NiwgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoNzcsIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDc4LCBmaWVsZFJlcXVpcmVkQm9vbDc4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA3OSwgZmllbGRSZXF1aXJlZFN0cmluZzc5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg4MCwgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcyg4MSwgZmllbGRSZXF1aXJlZEJ5dGVzODFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoODIsIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oODMsIGZpZWxkUmVxdWlyZWRFbnVtODNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMig4NCwgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCg4NSwgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoODYsIGZpZWxkUmVxdWlyZWRTaW50MzI4Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCg4NywgZmllbGRSZXF1aXJlZFNpbnQ2NDg3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoODgsIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxLCBmaWVsZERvdWJsZTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDIsIGZpZWxkRmxvYXQyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgzLCBmaWVsZEludDY0M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDQsIGZpZWxkVWludDY0NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNSwgZmllbGRJbnQzMjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoNiwgZmllbGRGaXhlZDY0Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSg3LCBmaWVsZEZpeGVkMzI3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDgsIGZpZWxkQm9vbDhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDksIGZpZWxkU3RyaW5nOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZ2V0RmllbGRNZXNzYWdlMTAoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxMSwgZmllbGRCeXRlczExXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMTIsIGZpZWxkVWludDMyMTJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTMsIGZpZWxkRW51bTEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSgxNCwgZmllbGRTZml4ZWQzMjE0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgxNSwgZmllbGRTZml4ZWQ2NDE1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoMTYsIGZpZWxkU2ludDMyMTZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSgxNywgZmllbGRTaW50NjQxN18pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhmaWVsZEludDY0TGlzdDIwXy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjcsIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGkpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkQnl0ZXNMaXN0MjhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcoZmllbGRCeXRlc0xpc3QyOF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDMyTGlzdDI5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFVpbnQzMkxpc3QyOUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEVudW1MaXN0MzBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhmaWVsZEVudW1MaXN0MzBfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZmllbGRFbnVtTGlzdDMwXy5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdDM0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcoZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfWZpZWxkRW51bUxpc3RQYWNrZWQ0NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcoZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDQ5LCBnZXRGaWVsZEdyb3VwNDkoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEdyb3VwTGlzdDUxXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoNTEsIGZpZWxkR3JvdXBMaXN0NTFfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDUzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoCiAgICAgICAgICAgICAgNTMsIChkb3VibGUpKChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgKICAgICAgICAgICAgICA1NCwgKGZsb2F0KSgoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgKICAgICAgICAgICAgICA1NSwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKAogICAgICAgICAgICAgIDU2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgKICAgICAgICAgICAgICA1NywgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKAogICAgICAgICAgICAgIDU4LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKAogICAgICAgICAgICAgIDU5LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoCiAgICAgICAgICAgICAgNjAsIChib29sZWFuKSgoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDYxLCB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjIsIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKAogICAgICAgICAgICAgIDYzLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgKICAgICAgICAgICAgICA2NCwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSgKICAgICAgICAgICAgICA2NSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY2KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgKICAgICAgICAgICAgICA2NiwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplKAogICAgICAgICAgICAgIDY3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSgKICAgICAgICAgICAgICA2OCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoNjksIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSkgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoNzEsIGZpZWxkUmVxdWlyZWREb3VibGU3MV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoNzIsIGZpZWxkUmVxdWlyZWRGbG9hdDcyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSg3MywgZmllbGRSZXF1aXJlZEludDY0NzNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZSg3NCwgZmllbGRSZXF1aXJlZFVpbnQ2NDc0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg3NSwgZmllbGRSZXF1aXJlZEludDMyNzVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoNzYsIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQzMlNpemUoNzcsIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoNzgsIGZpZWxkUmVxdWlyZWRCb29sNzhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDc5LCBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODAsIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSg4MSwgZmllbGRSZXF1aXJlZEJ5dGVzODFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSg4MiwgZmllbGRSZXF1aXJlZFVpbnQzMjgyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDgzLCBmaWVsZFJlcXVpcmVkRW51bTgzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSg4NCwgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkNjRTaXplKDg1LCBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplKDg2LCBmaWVsZFJlcXVpcmVkU2ludDMyODZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSg4NywgZmllbGRSZXF1aXJlZFNpbnQ2NDg3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSg4OCwgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODgoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzRmllbGREb3VibGUxKCkgIT0gb3RoZXIuaGFzRmllbGREb3VibGUxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkRG91YmxlMSgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTEoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0RmllbGREb3VibGUxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRmxvYXQyKCkgIT0gb3RoZXIuaGFzRmllbGRGbG9hdDIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRGbG9hdDIoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmllbGRGbG9hdDIoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0RmllbGRGbG9hdDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRJbnQ2NDMoKSAhPSBvdGhlci5oYXNGaWVsZEludDY0MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEludDY0MygpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkSW50NjQzKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQ2NDMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFVpbnQ2NDQoKSAhPSBvdGhlci5oYXNGaWVsZFVpbnQ2NDQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRVaW50NjQ0KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRVaW50NjQ0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRVaW50NjQ0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRJbnQzMjUoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEludDMyNSgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkSW50MzI1KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEZpeGVkNjQ2KCkgIT0gb3RoZXIuaGFzRmllbGRGaXhlZDY0NigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEZpeGVkNjQ2KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRGaXhlZDY0NigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkRml4ZWQ2NDYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEZpeGVkMzI3KCkgIT0gb3RoZXIuaGFzRmllbGRGaXhlZDMyNygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEZpeGVkMzI3KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyNygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkRml4ZWQzMjcoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEJvb2w4KCkgIT0gb3RoZXIuaGFzRmllbGRCb29sOCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEJvb2w4KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRCb29sOCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkQm9vbDgoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFN0cmluZzkoKSAhPSBvdGhlci5oYXNGaWVsZFN0cmluZzkoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRTdHJpbmc5KCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkU3RyaW5nOSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTdHJpbmc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkgIT0gb3RoZXIuaGFzRmllbGRNZXNzYWdlMTAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRNZXNzYWdlMTAoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkTWVzc2FnZTEwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkQnl0ZXMxMSgpICE9IG90aGVyLmhhc0ZpZWxkQnl0ZXMxMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEJ5dGVzMTEoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRCeXRlczExKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEJ5dGVzMTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRVaW50MzIxMigpICE9IG90aGVyLmhhc0ZpZWxkVWludDMyMTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRVaW50MzIxMigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkVWludDMyMTIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFVpbnQzMjEyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRFbnVtMTMoKSAhPSBvdGhlci5oYXNGaWVsZEVudW0xMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEVudW0xMygpKSB7CiAgICAgICAgaWYgKGZpZWxkRW51bTEzXyAhPSBvdGhlci5maWVsZEVudW0xM18pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTZml4ZWQzMjE0KCkgIT0gb3RoZXIuaGFzRmllbGRTZml4ZWQzMjE0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkU2ZpeGVkMzIxNCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkMzIxNCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkMzIxNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU2ZpeGVkNjQxNSgpICE9IG90aGVyLmhhc0ZpZWxkU2ZpeGVkNjQxNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFNmaXhlZDY0MTUoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0MTUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFNmaXhlZDY0MTUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNpbnQzMjE2KCkgIT0gb3RoZXIuaGFzRmllbGRTaW50MzIxNigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFNpbnQzMjE2KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRTaW50MzIxNigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDMyMTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNpbnQ2NDE3KCkgIT0gb3RoZXIuaGFzRmllbGRTaW50NjQxNygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFNpbnQ2NDE3KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRTaW50NjQxNygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDY0MTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRJbnQ2NExpc3QyMExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkQm9vbExpc3QyNUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZmllbGRFbnVtTGlzdDMwXy5lcXVhbHMob3RoZXIuZmllbGRFbnVtTGlzdDMwXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZXF1YWxzKG90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkR3JvdXA0OSgpICE9IG90aGVyLmhhc0ZpZWxkR3JvdXA0OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEdyb3VwNDkoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRHcm91cDQ5KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEdyb3VwNDkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldEZpZWxkR3JvdXBMaXN0NTFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRHcm91cExpc3Q1MUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGRSZXF1aXJlZERvdWJsZTcxKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldEZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkSW50NjQ3MygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRJbnQzMjc1KCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkSW50MzI3NSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEJvb2w3OCgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEJvb2w3OCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRCb29sNzgoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkQm9vbDc4KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEJ5dGVzODEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRVaW50MzI4MigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkRW51bTgzXyAhPSBvdGhlci5maWVsZFJlcXVpcmVkRW51bTgzXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRTaW50MzI4NigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkUmVxdWlyZWRTaW50MzI4NigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTaW50NjQ4NygpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTaW50NjQ4NygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRHcm91cDg4KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRHcm91cDg4KCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VGVzdE9uZW9mQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRUZXN0T25lb2ZDYXNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHN3aXRjaCAodGVzdE9uZW9mQ2FzZV8pIHsKICAgICAgICBjYXNlIDUzOgogICAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTUzKCkpCiAgICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZERvdWJsZTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU0OgogICAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRGaWVsZEZsb2F0NTQoKSkKICAgICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkRmxvYXQ1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NToKICAgICAgICAgIGlmIChnZXRGaWVsZEludDY0NTUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50NjQ1NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU2OgogICAgICAgICAgaWYgKGdldEZpZWxkVWludDY0NTYoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDY0NTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NzoKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyNTcoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI1NygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NDU4KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkNjQ1OCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQzMjU5KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkMzI1OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYwOgogICAgICAgICAgaWYgKGdldEZpZWxkQm9vbDYwKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEJvb2w2MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgaWYgKCFnZXRGaWVsZFN0cmluZzYxKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nNjEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjI6CiAgICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTYyKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkTWVzc2FnZTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYzOgogICAgICAgICAgaWYgKCFnZXRGaWVsZEJ5dGVzNjMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlczYzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY0OgogICAgICAgICAgaWYgKGdldEZpZWxkVWludDMyNjQoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NToKICAgICAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyNjUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkMzI2NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY2OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkNjQ2NigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDY2KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICBpZiAoZ2V0RmllbGRTaW50MzI2NygpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTaW50MzI2NygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ludDY0NjgoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDY0NjgoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2OToKICAgICAgICAgIGlmICghZ2V0RmllbGRHcm91cDY5KCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkR3JvdXA2OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRmllbGREb3VibGUxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9ET1VCTEVfMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldEZpZWxkRG91YmxlMSgpKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRmxvYXQyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF8yX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldEZpZWxkRmxvYXQyKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEludDY0MygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UNjRfM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0RmllbGRJbnQ2NDMoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkVWludDY0NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDY0XzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkVWludDY0NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRJbnQzMjUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzI1KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRml4ZWQ2NDYoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0RmllbGRGaXhlZDY0NigpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRGaXhlZDMyNygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQzMl83X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkMzI3KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkQm9vbDgoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0RmllbGRCb29sOCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTdHJpbmc5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TVFJJTkdfOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTdHJpbmc5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRCeXRlczExKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CWVRFU18xMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRCeXRlczExKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRVaW50MzIxMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyXzEyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQzMjEyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRW51bTEzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9FTlVNXzEzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBmaWVsZEVudW0xM187CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU2ZpeGVkMzIxNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkMzIxNCgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNmaXhlZDY0MTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDY0XzE1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFNmaXhlZDY0MTUoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU2ludDMyMTYoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQzMl8xNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzIxNigpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNpbnQ2NDE3KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UNjRfMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkU2ludDY0MTcoKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRG91YmxlTGlzdDE4Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9ET1VCTEVfTElTVF8xOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRkxPQVRfTElTVF8xOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDY0TGlzdDIwQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQ2NF9MSVNUXzIwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkVWludDY0TGlzdDIxQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UNjRfTElTVF8yMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQzMkxpc3QyMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfTElTVF8yMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkNjRMaXN0MjNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVENjRfTElTVF8yM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRml4ZWQzMkxpc3QyNENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQzMl9MSVNUXzI0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRCb29sTGlzdDI1Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MX0xJU1RfMjVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HX0xJU1RfMjZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUVTU0FHRV9MSVNUXzI3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfQllURVNfTElTVF8yOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRCeXRlc0xpc3QyOExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMkxpc3QyOUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyX0xJU1RfMjlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRW51bUxpc3QzMENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRU5VTV9MSVNUXzMwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBmaWVsZEVudW1MaXN0MzBfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDMyX0xJU1RfMzFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVENjRfTElTVF8zMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0lOVDMyX0xJU1RfMzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ludDY0TGlzdDM0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UNjRfTElTVF8zNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0RPVUJMRV9MSVNUX1BBQ0tFRF8zNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRkxPQVRfTElTVF9QQUNLRURfMzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UNjRfTElTVF9QQUNLRURfMzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF9MSVNUX1BBQ0tFRF8zOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfTElTVF9QQUNLRURfMzlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDY0X0xJU1RfUEFDS0VEXzQwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDMyX0xJU1RfUEFDS0VEXzQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MX0xJU1RfUEFDS0VEXzQyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQzMl9MSVNUX1BBQ0tFRF80M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9FTlVNX0xJU1RfUEFDS0VEXzQ0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDMyX0xJU1RfUEFDS0VEXzQ1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDY0X0xJU1RfUEFDS0VEXzQ2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfTElTVF9QQUNLRURfNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UNjRfTElTVF9QQUNLRURfNDhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkR3JvdXA0OSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERHUk9VUDQ5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEdyb3VwNDkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEdyb3VwTGlzdDUxQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMREdST1VQTElTVDUxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEdyb3VwTGlzdDUxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfRE9VQkxFXzcxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGRSZXF1aXJlZERvdWJsZTcxKCkpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEZsb2F0NzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0ZMT0FUXzcyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkSW50NjQ3MygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfSU5UNjRfNzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX1VJTlQ2NF83NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfSU5UMzJfNzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRJbnQzMjc1KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0ZJWEVENjRfNzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0ZJWEVEMzJfNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEJvb2w3OCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfQk9PTF83OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZEJvb2w3OCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9TVFJJTkdfNzlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX01FU1NBR0VfODBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfQllURVNfODFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRCeXRlczgxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9VSU5UMzJfODJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9FTlVNXzgzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBmaWVsZFJlcXVpcmVkRW51bTgzXzsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX1NGSVhFRDMyXzg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfU0ZJWEVENjRfODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ludDMyODYoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX1NJTlQzMl84Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRSZXF1aXJlZFNpbnQzMjg2KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTaW50NjQ4NygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfU0lOVDY0Xzg3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRHcm91cDg4KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRFJFUVVJUkVER1JPVVA4OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIHN3aXRjaCAodGVzdE9uZW9mQ2FzZV8pIHsKICAgICAgICBjYXNlIDUzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRE9VQkxFXzUzX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldEZpZWxkRG91YmxlNTMoKSkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NDoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZMT0FUXzU0X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICBnZXRGaWVsZEZsb2F0NTQoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU1OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UNjRfNTVfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgICBnZXRGaWVsZEludDY0NTUoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU2OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDY0XzU2X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRVaW50NjQ1NigpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTc6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl81N19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNTcoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTg6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDY0XzU4X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRGaXhlZDY0NTgoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQzMl81OV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkMzI1OSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MDoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfNjBfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgICBnZXRGaWVsZEJvb2w2MCgpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TVFJJTkdfNjFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTdHJpbmc2MSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUVTU0FHRV82Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE1lc3NhZ2U2MigpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfQllURVNfNjNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRCeXRlczYzKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjQ6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50MzI2NCgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDMyXzY1X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkMzI2NSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDY0XzY2X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NDY2KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQzMl82N19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQzMjY3KCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0lOVDY0XzY4X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRTaW50NjQ2OCgpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjk6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMREdST1VQNjlfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRHcm91cDY5KCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlMTBGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRHcm91cDQ5RmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZEdyb3VwTGlzdDUxRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgYml0RmllbGQyXyA9IDA7CiAgICAgICAgZmllbGREb3VibGUxXyA9IDBEOwogICAgICAgIGZpZWxkRmxvYXQyXyA9IDBGOwogICAgICAgIGZpZWxkSW50NjQzXyA9IDBMOwogICAgICAgIGZpZWxkVWludDY0NF8gPSAwTDsKICAgICAgICBmaWVsZEludDMyNV8gPSAwOwogICAgICAgIGZpZWxkRml4ZWQ2NDZfID0gMEw7CiAgICAgICAgZmllbGRGaXhlZDMyN18gPSAwOwogICAgICAgIGZpZWxkQm9vbDhfID0gZmFsc2U7CiAgICAgICAgZmllbGRTdHJpbmc5XyA9ICIiOwogICAgICAgIGZpZWxkTWVzc2FnZTEwXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICBmaWVsZFVpbnQzMjEyXyA9IDA7CiAgICAgICAgZmllbGRFbnVtMTNfID0gMDsKICAgICAgICBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgICAgICBmaWVsZFNmaXhlZDY0MTVfID0gMEw7CiAgICAgICAgZmllbGRTaW50MzIxNl8gPSAwOwogICAgICAgIGZpZWxkU2ludDY0MTdfID0gMEw7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkQm9vbExpc3QyNV8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gbnVsbDsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGZpZWxkVWludDMyTGlzdDI5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkRW51bUxpc3QzMF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkR3JvdXA0OV8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEdyb3VwNDlCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gbnVsbDsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRHcm91cDY5QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRHcm91cDY5QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgZmllbGRSZXF1aXJlZERvdWJsZTcxXyA9IDBEOwogICAgICAgIGZpZWxkUmVxdWlyZWRGbG9hdDcyXyA9IDBGOwogICAgICAgIGZpZWxkUmVxdWlyZWRJbnQ2NDczXyA9IDBMOwogICAgICAgIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF8gPSAwTDsKICAgICAgICBmaWVsZFJlcXVpcmVkSW50MzI3NV8gPSAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfID0gMEw7CiAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkMzI3N18gPSAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRCb29sNzhfID0gZmFsc2U7CiAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9ICIiOwogICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmaWVsZFJlcXVpcmVkQnl0ZXM4MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgZmllbGRSZXF1aXJlZFVpbnQzMjgyXyA9IDA7CiAgICAgICAgZmllbGRSZXF1aXJlZEVudW04M18gPSAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XyA9IDA7CiAgICAgICAgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfID0gMEw7CiAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA9IDA7CiAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQ2NDg3XyA9IDBMOwogICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4XyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDJfICE9IDApIHsgYnVpbGRQYXJ0aWFsMihyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuZmllbGRNZXNzYWdlTGlzdDI3XyA9IGZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1lc3NhZ2VMaXN0MjdfID0gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRFbnVtTGlzdDMwXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5maWVsZEVudW1MaXN0MzBfID0gZmllbGRFbnVtTGlzdDMwXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBmaWVsZEVudW1MaXN0UGFja2VkNDRfOwogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuZmllbGRHcm91cExpc3Q1MV8gPSBmaWVsZEdyb3VwTGlzdDUxXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LmZpZWxkR3JvdXBMaXN0NTFfID0gZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRG91YmxlMV8gPSBmaWVsZERvdWJsZTFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRmxvYXQyXyA9IGZpZWxkRmxvYXQyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDY0M18gPSBmaWVsZEludDY0M187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50NjQ0XyA9IGZpZWxkVWludDY0NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQzMjVfID0gZmllbGRJbnQzMjVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQ2NDZfID0gZmllbGRGaXhlZDY0Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDMyN18gPSBmaWVsZEZpeGVkMzI3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEJvb2w4XyA9IGZpZWxkQm9vbDhfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkU3RyaW5nOV8gPSBmaWVsZFN0cmluZzlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWVzc2FnZTEwXyA9IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRNZXNzYWdlMTBfCiAgICAgICAgICAgICAgOiBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRCeXRlczExXyA9IGZpZWxkQnl0ZXMxMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50MzIxMl8gPSBmaWVsZFVpbnQzMjEyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEVudW0xM18gPSBmaWVsZEVudW0xM187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQzMjE0XyA9IGZpZWxkU2ZpeGVkMzIxNF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQ2NDE1XyA9IGZpZWxkU2ZpeGVkNjQxNV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50MzIxNl8gPSBmaWVsZFNpbnQzMjE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQ2NDE3XyA9IGZpZWxkU2ludDY0MTdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZERvdWJsZUxpc3QxOF8gPSBmaWVsZERvdWJsZUxpc3QxOF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGbG9hdExpc3QxOV8gPSBmaWVsZEZsb2F0TGlzdDE5XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDY0TGlzdDIwXyA9IGZpZWxkSW50NjRMaXN0MjBfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQ2NExpc3QyMV8gPSBmaWVsZFVpbnQ2NExpc3QyMV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQzMkxpc3QyMl8gPSBmaWVsZEludDMyTGlzdDIyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQ2NExpc3QyM18gPSBmaWVsZEZpeGVkNjRMaXN0MjNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDMyTGlzdDI0XyA9IGZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEJvb2xMaXN0MjVfID0gZmllbGRCb29sTGlzdDI1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTdHJpbmdMaXN0MjZfID0gZmllbGRTdHJpbmdMaXN0MjZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkQnl0ZXNMaXN0MjhfID0gZmllbGRCeXRlc0xpc3QyOF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDMyTGlzdDI5XyA9IGZpZWxkVWludDMyTGlzdDI5XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDMyTGlzdDMxXyA9IGZpZWxkU2ZpeGVkMzJMaXN0MzFfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxXyA9IGJpdEZpZWxkMV87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50MzJMaXN0MzNfID0gZmllbGRTaW50MzJMaXN0MzNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQ2NExpc3QzNF8gPSBmaWVsZFNpbnQ2NExpc3QzNF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IGZpZWxkSW50MzJMaXN0UGFja2VkMzlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBmaWVsZEJvb2xMaXN0UGFja2VkNDJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8gPSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XyA9IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRHcm91cDQ5XyA9IGZpZWxkR3JvdXA0OUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZpZWxkR3JvdXA0OV8KICAgICAgICAgICAgICA6IGZpZWxkR3JvdXA0OUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyXyA9IGJpdEZpZWxkMl87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZERvdWJsZTcxXyA9IGZpZWxkUmVxdWlyZWREb3VibGU3MV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZEZsb2F0NzJfID0gZmllbGRSZXF1aXJlZEZsb2F0NzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRJbnQ2NDczXyA9IGZpZWxkUmVxdWlyZWRJbnQ2NDczXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkVWludDY0NzRfID0gZmllbGRSZXF1aXJlZFVpbnQ2NDc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkSW50MzI3NV8gPSBmaWVsZFJlcXVpcmVkSW50MzI3NV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gPSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkRml4ZWQzMjc3XyA9IGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRCb29sNzhfID0gZmllbGRSZXF1aXJlZEJvb2w3OF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IGZpZWxkUmVxdWlyZWRTdHJpbmc3OV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8KICAgICAgICAgICAgICA6IGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IGZpZWxkUmVxdWlyZWRCeXRlczgxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkVWludDMyODJfID0gZmllbGRSZXF1aXJlZFVpbnQzMjgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkRW51bTgzXyA9IGZpZWxkUmVxdWlyZWRFbnVtODNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XyA9IGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfID0gZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRTaW50MzI4Nl8gPSBmaWVsZFJlcXVpcmVkU2ludDMyODZfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRTaW50NjQ4N18gPSBmaWVsZFJlcXVpcmVkU2ludDY0ODdfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRHcm91cDg4XyA9IGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRSZXF1aXJlZEdyb3VwODhfCiAgICAgICAgICAgICAgOiBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMV8gfD0gdG9fYml0RmllbGQxXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIHJlc3VsdC50ZXN0T25lb2ZDYXNlXyA9IHRlc3RPbmVvZkNhc2VfOwogICAgICAgIHJlc3VsdC50ZXN0T25lb2ZfID0gdGhpcy50ZXN0T25lb2ZfOwogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MiAmJgogICAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlc3VsdC50ZXN0T25lb2ZfID0gZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjkgJiYKICAgICAgICAgICAgZmllbGRHcm91cDY5QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LnRlc3RPbmVvZl8gPSBmaWVsZEdyb3VwNjlCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzRmllbGREb3VibGUxKCkpIHsKICAgICAgICAgIHNldEZpZWxkRG91YmxlMShvdGhlci5nZXRGaWVsZERvdWJsZTEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEZsb2F0MigpKSB7CiAgICAgICAgICBzZXRGaWVsZEZsb2F0MihvdGhlci5nZXRGaWVsZEZsb2F0MigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkSW50NjQzKCkpIHsKICAgICAgICAgIHNldEZpZWxkSW50NjQzKG90aGVyLmdldEZpZWxkSW50NjQzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRVaW50NjQ0KCkpIHsKICAgICAgICAgIHNldEZpZWxkVWludDY0NChvdGhlci5nZXRGaWVsZFVpbnQ2NDQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEludDMyNSgpKSB7CiAgICAgICAgICBzZXRGaWVsZEludDMyNShvdGhlci5nZXRGaWVsZEludDMyNSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkRml4ZWQ2NDYoKSkgewogICAgICAgICAgc2V0RmllbGRGaXhlZDY0NihvdGhlci5nZXRGaWVsZEZpeGVkNjQ2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRGaXhlZDMyNygpKSB7CiAgICAgICAgICBzZXRGaWVsZEZpeGVkMzI3KG90aGVyLmdldEZpZWxkRml4ZWQzMjcoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEJvb2w4KCkpIHsKICAgICAgICAgIHNldEZpZWxkQm9vbDgob3RoZXIuZ2V0RmllbGRCb29sOCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkU3RyaW5nOSgpKSB7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gb3RoZXIuZmllbGRTdHJpbmc5XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZE1lc3NhZ2UxMChvdGhlci5nZXRGaWVsZE1lc3NhZ2UxMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkQnl0ZXMxMSgpKSB7CiAgICAgICAgICBzZXRGaWVsZEJ5dGVzMTEob3RoZXIuZ2V0RmllbGRCeXRlczExKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRVaW50MzIxMigpKSB7CiAgICAgICAgICBzZXRGaWVsZFVpbnQzMjEyKG90aGVyLmdldEZpZWxkVWludDMyMTIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEVudW0xMygpKSB7CiAgICAgICAgICBzZXRGaWVsZEVudW0xMyhvdGhlci5nZXRGaWVsZEVudW0xMygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkU2ZpeGVkMzIxNCgpKSB7CiAgICAgICAgICBzZXRGaWVsZFNmaXhlZDMyMTQob3RoZXIuZ2V0RmllbGRTZml4ZWQzMjE0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRTZml4ZWQ2NDE1KCkpIHsKICAgICAgICAgIHNldEZpZWxkU2ZpeGVkNjQxNShvdGhlci5nZXRGaWVsZFNmaXhlZDY0MTUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFNpbnQzMjE2KCkpIHsKICAgICAgICAgIHNldEZpZWxkU2ludDMyMTYob3RoZXIuZ2V0RmllbGRTaW50MzIxNigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkU2ludDY0MTcoKSkgewogICAgICAgICAgc2V0RmllbGRTaW50NjQxNyhvdGhlci5nZXRGaWVsZFNpbnQ2NDE3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRG91YmxlTGlzdDE4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZERvdWJsZUxpc3QxOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IG90aGVyLmZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLmFkZEFsbChvdGhlci5maWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGbG9hdExpc3QxOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGbG9hdExpc3QxOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gb3RoZXIuZmllbGRGbG9hdExpc3QxOV87CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRBbGwob3RoZXIuZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQ2NExpc3QyMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQ2NExpc3QyMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gb3RoZXIuZmllbGRJbnQ2NExpc3QyMF87CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5hZGRBbGwob3RoZXIuZmllbGRJbnQ2NExpc3QyMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50NjRMaXN0MjFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDY0TGlzdDIxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfID0gb3RoZXIuZmllbGRVaW50NjRMaXN0MjFfOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uYWRkQWxsKG90aGVyLmZpZWxkVWludDY0TGlzdDIxXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEludDMyTGlzdDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEludDMyTGlzdDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBvdGhlci5maWVsZEludDMyTGlzdDIyXzsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEFsbChvdGhlci5maWVsZEludDMyTGlzdDIyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRml4ZWQ2NExpc3QyM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkQWxsKG90aGVyLmZpZWxkRml4ZWQ2NExpc3QyM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkMzJMaXN0MjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gb3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0XzsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQm9vbExpc3QyNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRCb29sTGlzdDI1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG90aGVyLmZpZWxkQm9vbExpc3QyNV87CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1Xy5hZGRBbGwob3RoZXIuZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFN0cmluZ0xpc3QyNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTdHJpbmdMaXN0MjZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPSBvdGhlci5maWVsZFN0cmluZ0xpc3QyNl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGRBbGwob3RoZXIuZmllbGRTdHJpbmdMaXN0MjZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGRBbGwob3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG90aGVyLmZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkQnl0ZXNMaXN0MjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IG90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfOwogICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uYWRkQWxsKG90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkVWludDMyTGlzdDI5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFVpbnQzMkxpc3QyOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5XyA9IG90aGVyLmZpZWxkVWludDMyTGlzdDI5XzsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEFsbChvdGhlci5maWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRFbnVtTGlzdDMwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEVudW1MaXN0MzBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gb3RoZXIuZmllbGRFbnVtTGlzdDMwXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkQWxsKG90aGVyLmZpZWxkRW51bUxpc3QzMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gb3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5hZGRBbGwob3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gb3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRBbGwob3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50MzJMaXN0MzNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDMyTGlzdDMzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gb3RoZXIuZmllbGRTaW50MzJMaXN0MzNfOwogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uYWRkQWxsKG90aGVyLmZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFNpbnQ2NExpc3QzNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTaW50NjRMaXN0MzRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBvdGhlci5maWVsZFNpbnQ2NExpc3QzNF87CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRBbGwob3RoZXIuZmllbGRTaW50NjRMaXN0MzRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IG90aGVyLmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZEFsbChvdGhlci5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gb3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRBbGwob3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gb3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRBbGwob3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gb3RoZXIuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkQWxsKG90aGVyLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEFsbChvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkQWxsKG90aGVyLmZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gb3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRCb29sTGlzdFBhY2tlZDQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IG90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRBbGwob3RoZXIuZmllbGRCb29sTGlzdFBhY2tlZDQyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBvdGhlci5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRBbGwob3RoZXIuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IG90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZEFsbChvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9IG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9IG90aGVyLmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0UGFja2VkNDdJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEFsbChvdGhlci5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gb3RoZXIuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkQWxsKG90aGVyLmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkR3JvdXA0OSgpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkR3JvdXA0OShvdGhlci5nZXRGaWVsZEdyb3VwNDkoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5maWVsZEdyb3VwTGlzdDUxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gb3RoZXIuZmllbGRHcm91cExpc3Q1MV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMjAwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5hZGRBbGwob3RoZXIuZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLmZpZWxkR3JvdXBMaXN0NTFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXyA9IG90aGVyLmZpZWxkR3JvdXBMaXN0NTFfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0RmllbGRHcm91cExpc3Q1MUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZERvdWJsZTcxKG90aGVyLmdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRGbG9hdDcyKG90aGVyLmdldEZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZEludDY0NzMob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEludDY0NzMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZFVpbnQ2NDc0KG90aGVyLmdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRJbnQzMjc1KG90aGVyLmdldEZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KG90aGVyLmdldEZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEZpeGVkMzI3NygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZEJvb2w3OChvdGhlci5nZXRGaWVsZFJlcXVpcmVkQm9vbDc4KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkpIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSBvdGhlci5maWVsZFJlcXVpcmVkU3RyaW5nNzlfOwogICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpIHsKICAgICAgICAgIG1lcmdlRmllbGRSZXF1aXJlZE1lc3NhZ2U4MChvdGhlci5nZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZEJ5dGVzODEob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEJ5dGVzODEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkVWludDMyODIoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZFVpbnQzMjgyKG90aGVyLmdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZEVudW04MyhvdGhlci5nZXRGaWVsZFJlcXVpcmVkRW51bTgzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQob3RoZXIuZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NShvdGhlci5nZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkU2ludDMyODYob3RoZXIuZ2V0RmllbGRSZXF1aXJlZFNpbnQzMjg2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRTaW50NjQ4NyhvdGhlci5nZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkUmVxdWlyZWRHcm91cDg4KG90aGVyLmdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCkpOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKG90aGVyLmdldFRlc3RPbmVvZkNhc2UoKSkgewogICAgICAgICAgY2FzZSBGSUVMRF9ET1VCTEVfNTM6IHsKICAgICAgICAgICAgc2V0RmllbGREb3VibGU1MyhvdGhlci5nZXRGaWVsZERvdWJsZTUzKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfRkxPQVRfNTQ6IHsKICAgICAgICAgICAgc2V0RmllbGRGbG9hdDU0KG90aGVyLmdldEZpZWxkRmxvYXQ1NCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0lOVDY0XzU1OiB7CiAgICAgICAgICAgIHNldEZpZWxkSW50NjQ1NShvdGhlci5nZXRGaWVsZEludDY0NTUoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9VSU5UNjRfNTY6IHsKICAgICAgICAgICAgc2V0RmllbGRVaW50NjQ1NihvdGhlci5nZXRGaWVsZFVpbnQ2NDU2KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfSU5UMzJfNTc6IHsKICAgICAgICAgICAgc2V0RmllbGRJbnQzMjU3KG90aGVyLmdldEZpZWxkSW50MzI1NygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0ZJWEVENjRfNTg6IHsKICAgICAgICAgICAgc2V0RmllbGRGaXhlZDY0NTgob3RoZXIuZ2V0RmllbGRGaXhlZDY0NTgoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9GSVhFRDMyXzU5OiB7CiAgICAgICAgICAgIHNldEZpZWxkRml4ZWQzMjU5KG90aGVyLmdldEZpZWxkRml4ZWQzMjU5KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfQk9PTF82MDogewogICAgICAgICAgICBzZXRGaWVsZEJvb2w2MChvdGhlci5nZXRGaWVsZEJvb2w2MCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1NUUklOR182MTogewogICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYxOwogICAgICAgICAgICB0ZXN0T25lb2ZfID0gb3RoZXIudGVzdE9uZW9mXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9NRVNTQUdFXzYyOiB7CiAgICAgICAgICAgIG1lcmdlRmllbGRNZXNzYWdlNjIob3RoZXIuZ2V0RmllbGRNZXNzYWdlNjIoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9CWVRFU182MzogewogICAgICAgICAgICBzZXRGaWVsZEJ5dGVzNjMob3RoZXIuZ2V0RmllbGRCeXRlczYzKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfVUlOVDMyXzY0OiB7CiAgICAgICAgICAgIHNldEZpZWxkVWludDMyNjQob3RoZXIuZ2V0RmllbGRVaW50MzI2NCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1NGSVhFRDMyXzY1OiB7CiAgICAgICAgICAgIHNldEZpZWxkU2ZpeGVkMzI2NShvdGhlci5nZXRGaWVsZFNmaXhlZDMyNjUoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TRklYRUQ2NF82NjogewogICAgICAgICAgICBzZXRGaWVsZFNmaXhlZDY0NjYob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDY2KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfU0lOVDMyXzY3OiB7CiAgICAgICAgICAgIHNldEZpZWxkU2ludDMyNjcob3RoZXIuZ2V0RmllbGRTaW50MzI2NygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1NJTlQ2NF82ODogewogICAgICAgICAgICBzZXRGaWVsZFNpbnQ2NDY4KG90aGVyLmdldEZpZWxkU2ludDY0NjgoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMREdST1VQNjk6IHsKICAgICAgICAgICAgbWVyZ2VGaWVsZEdyb3VwNjkob3RoZXIuZ2V0RmllbGRHcm91cDY5KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgVEVTVE9ORU9GX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEZsb2F0NzIoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkVWludDMyODIoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRHcm91cDg4KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICAgIGlmICghZ2V0RmllbGRNZXNzYWdlMTAoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCk7IGkrKykgewogICAgICAgICAgaWYgKCFnZXRGaWVsZE1lc3NhZ2VMaXN0MjcoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTYyKCkpIHsKICAgICAgICAgIGlmICghZ2V0RmllbGRNZXNzYWdlNjIoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgOTogewogICAgICAgICAgICAgICAgZmllbGREb3VibGUxXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5CiAgICAgICAgICAgICAgY2FzZSAyMTogewogICAgICAgICAgICAgICAgZmllbGRGbG9hdDJfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDY0M18gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGZpZWxkVWludDY0NF8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDMyNV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDk6IHsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NDZfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OQogICAgICAgICAgICAgIGNhc2UgNjE6IHsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQzMjdfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbDhfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NAogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkU3RyaW5nOV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkVWludDMyMTJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZmllbGRFbnVtMTNfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMTc6IHsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzIxNF8gPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTcKICAgICAgICAgICAgICBjYXNlIDEyMTogewogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NDE1XyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMQogICAgICAgICAgICAgIGNhc2UgMTI4OiB7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMjE2XyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjgKICAgICAgICAgICAgICBjYXNlIDEzNjogewogICAgICAgICAgICAgICAgZmllbGRTaW50NjQxN18gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2CiAgICAgICAgICAgICAgY2FzZSAxNDU6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ1CiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTc6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NwogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjA6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAKICAgICAgICAgICAgICBjYXNlIDE2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTY4OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzAKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODU6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODUKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk3CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDA6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDAKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTdHJpbmdMaXN0MjZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGNhc2UgMjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHYgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLmFkZCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMjYKICAgICAgICAgICAgICBjYXNlIDIzMjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMzIKICAgICAgICAgICAgICBjYXNlIDIzNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjM0CiAgICAgICAgICAgICAgY2FzZSAyNDA6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDMwLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQwCiAgICAgICAgICAgICAgY2FzZSAyNDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMzAsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgZmllbGRFbnVtTGlzdDMwXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MgogICAgICAgICAgICAgIGNhc2UgMjUzOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MwogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MAogICAgICAgICAgICAgIGNhc2UgMjU3OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU3CiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1OAogICAgICAgICAgICAgIGNhc2UgMjY0OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NAogICAgICAgICAgICAgIGNhc2UgMjY2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNjYKICAgICAgICAgICAgICBjYXNlIDI3MjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3MgogICAgICAgICAgICAgIGNhc2UgMjc0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjc0CiAgICAgICAgICAgICAgY2FzZSAyODE6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgxCiAgICAgICAgICAgICAgY2FzZSAyODI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyOTM6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MwogICAgICAgICAgICAgIGNhc2UgMjkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjkwCiAgICAgICAgICAgICAgY2FzZSAyOTY6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTYKICAgICAgICAgICAgICBjYXNlIDI5ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA0OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA0CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDYKICAgICAgICAgICAgICBjYXNlIDMxMjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMTIKICAgICAgICAgICAgICBjYXNlIDMxNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE0CiAgICAgICAgICAgICAgY2FzZSAzMjE6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjEKICAgICAgICAgICAgICBjYXNlIDMyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIyCiAgICAgICAgICAgICAgY2FzZSAzMzM6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMzCiAgICAgICAgICAgICAgY2FzZSAzMzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMwCiAgICAgICAgICAgICAgY2FzZSAzMzY6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzYKICAgICAgICAgICAgICBjYXNlIDMzODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM4CiAgICAgICAgICAgICAgY2FzZSAzNDQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ0CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgMzUyOiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg0NCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM1MgogICAgICAgICAgICAgIGNhc2UgMzU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDQ0LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTQKICAgICAgICAgICAgICBjYXNlIDM2NTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjUKICAgICAgICAgICAgICBjYXNlIDM2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KGlucHV0LnJlYWRTRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjIKICAgICAgICAgICAgICBjYXNlIDM2OTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2OQogICAgICAgICAgICAgIGNhc2UgMzcwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKGlucHV0LnJlYWRTRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzAKICAgICAgICAgICAgICBjYXNlIDM3NjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzYKICAgICAgICAgICAgICBjYXNlIDM3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzc4CiAgICAgICAgICAgICAgY2FzZSAzODQ6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzODQKICAgICAgICAgICAgICBjYXNlIDM4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM4NgogICAgICAgICAgICAgIGNhc2UgMzk1OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoNDksCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRHcm91cDQ5RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzOTUKICAgICAgICAgICAgICBjYXNlIDQxMTogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCg1MSwKICAgICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDExCiAgICAgICAgICAgICAgY2FzZSA0MjU6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDUzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyNQogICAgICAgICAgICAgIGNhc2UgNDM3OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQzNwogICAgICAgICAgICAgIGNhc2UgNDQwOiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU1OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0MAogICAgICAgICAgICAgIGNhc2UgNDQ4OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NDgKICAgICAgICAgICAgICBjYXNlIDQ1NjogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NTYKICAgICAgICAgICAgICBjYXNlIDQ2NTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ2NQogICAgICAgICAgICAgIGNhc2UgNDc3OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDc3CiAgICAgICAgICAgICAgY2FzZSA0ODA6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0ODAKICAgICAgICAgICAgICBjYXNlIDQ5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYxOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ5MAogICAgICAgICAgICAgIGNhc2UgNDk4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2U2MkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ5OAogICAgICAgICAgICAgIGNhc2UgNTA2OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNgogICAgICAgICAgICAgIGNhc2UgNTEyOiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBjYXNlIDUyNTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjUKICAgICAgICAgICAgICBjYXNlIDUyOTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjkKICAgICAgICAgICAgICBjYXNlIDUzNjogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTM2CiAgICAgICAgICAgICAgY2FzZSA1NDQ6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU0NAogICAgICAgICAgICAgIGNhc2UgNTU1OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoNjksCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRHcm91cDY5RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTU1CiAgICAgICAgICAgICAgY2FzZSA1Njk6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWREb3VibGU3MV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTY5CiAgICAgICAgICAgICAgY2FzZSA1ODE6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRGbG9hdDcyXyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4MQogICAgICAgICAgICAgIGNhc2UgNTg0OiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkSW50NjQ3M18gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1ODQKICAgICAgICAgICAgICBjYXNlIDU5MjogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZFVpbnQ2NDc0XyA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OTIKICAgICAgICAgICAgICBjYXNlIDYwMDogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZEludDMyNzVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjAwCiAgICAgICAgICAgICAgY2FzZSA2MDk6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MDkKICAgICAgICAgICAgICBjYXNlIDYyMTogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkMzI3N18gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYyMQogICAgICAgICAgICAgIGNhc2UgNjI0OiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkQm9vbDc4XyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjI0CiAgICAgICAgICAgICAgY2FzZSA2MzQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MzQKICAgICAgICAgICAgICBjYXNlIDY0MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQyCiAgICAgICAgICAgICAgY2FzZSA2NTA6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY1MAogICAgICAgICAgICAgIGNhc2UgNjU2OiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkVWludDMyODJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY1NgogICAgICAgICAgICAgIGNhc2UgNjY0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg4MywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRFbnVtODNfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjY0CiAgICAgICAgICAgICAgY2FzZSA2Nzc6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XyA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY3NwogICAgICAgICAgICAgIGNhc2UgNjgxOiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV8gPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODEKICAgICAgICAgICAgICBjYXNlIDY4ODogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODgKICAgICAgICAgICAgICBjYXNlIDY5NjogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQ2NDg3XyA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2OTYKICAgICAgICAgICAgICBjYXNlIDcwNzogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDg4LAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MDcKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCB0ZXN0T25lb2ZfOwogICAgICBwdWJsaWMgVGVzdE9uZW9mQ2FzZQogICAgICAgICAgZ2V0VGVzdE9uZW9mQ2FzZSgpIHsKICAgICAgICByZXR1cm4gVGVzdE9uZW9mQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUZXN0T25lb2YoKSB7CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDJfOwoKICAgICAgcHJpdmF0ZSBkb3VibGUgZmllbGREb3VibGUxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGUxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlMSgpIHsKICAgICAgICByZXR1cm4gZmllbGREb3VibGUxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGUxKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBmaWVsZERvdWJsZTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZERvdWJsZTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkRG91YmxlMV8gPSAwRDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmbG9hdCBmaWVsZEZsb2F0Ml8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGbG9hdDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDIoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdDIoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGbG9hdDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdDIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGZpZWxkRmxvYXQyXyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRJbnQ2NDNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDMoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjQzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NDMobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZEludDY0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZmllbGRJbnQ2NDNfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZFVpbnQ2NDRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0NCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjQ0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjQ0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRVaW50NjQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50NjQ0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjUoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkSW50MzI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBmaWVsZEludDMyNV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRGaXhlZDY0Nl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBmaWVsZF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkNjQ2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDY0NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NDYoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NDZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjQ2KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDY0NigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRGaXhlZDMyN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyNygpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQzMjcoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGZpZWxkQm9vbDhfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQm9vbDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w4LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2w4KCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2w4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2w4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sOChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGZpZWxkQm9vbDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQm9vbDgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGZpZWxkQm9vbDhfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZFN0cmluZzlfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFN0cmluZzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTdHJpbmc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBmaWVsZFN0cmluZzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTdHJpbmc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRTdHJpbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmc5KCkgewogICAgICAgIGZpZWxkU3RyaW5nOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZFN0cmluZzkoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRTdHJpbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGZpZWxkTWVzc2FnZTEwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlMTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNZXNzYWdlMTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRNZXNzYWdlMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWVzc2FnZTEwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkTWVzc2FnZTEwXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlMTAoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkTWVzc2FnZTEwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRNZXNzYWdlMTBfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRNZXNzYWdlMTBfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmllbGRNZXNzYWdlMTBCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkTWVzc2FnZTEwXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNZXNzYWdlMTAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGZpZWxkTWVzc2FnZTEwXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxMEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2UxMEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxME9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkTWVzc2FnZTEwXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2UxMCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGZpZWxkQnl0ZXMxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzMTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzMTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlczExLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXMxMSgpIHsKICAgICAgICByZXR1cm4gZmllbGRCeXRlczExXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCeXRlczExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCeXRlczExKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRCeXRlczExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCeXRlczExKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBmaWVsZEJ5dGVzMTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RmllbGRCeXRlczExKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkVWludDMyMTJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzIxMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDMyMTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZmllbGRfdWludDMyXzEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMjEyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyMTIoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyMTJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZmllbGRfdWludDMyXzEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDMyMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQzMjEyKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZFVpbnQzMjEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQzMjEyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBmaWVsZFVpbnQzMjEyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkRW51bTEzXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEVudW0xMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRW51bTEzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bTEzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZEVudW0xMygpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkRW51bTEzXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEVudW0xMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bTEzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBmaWVsZEVudW0xM18gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRFbnVtMTMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkMzIxNF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjE0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjE0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzIxNC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyMTQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzIxNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzIxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkMzIxNChpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQzMjE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ZpeGVkNjQxNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDE1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQ2NDE1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQxNS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDE1KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0MTUobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFNmaXhlZDY0MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGZpZWxkU2ZpeGVkNjQxNV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50MzIxNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQzMjE2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyMTYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50MzIxNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50MzIxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ludDMyMTYoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkU2ludDMyMTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZmllbGRfc2ludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDMyMTYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGZpZWxkU2ludDMyMTZfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ludDY0MTdfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBmaWVsZF9zaW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQxNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0MTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDE3LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NDE3KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NDE3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NDE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjQxNyhsb25nIHZhbHVlKSB7CgogICAgICAgIGZpZWxkU2ludDY0MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGZpZWxkU2ludDY0MTdfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZERvdWJsZUxpc3QxOF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGREb3VibGVMaXN0MThfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGREb3VibGVMaXN0MThfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKSB7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0MThfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRG91YmxlTGlzdDE4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGVMaXN0MTggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3QxOChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0MThfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGVMaXN0MTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZERvdWJsZUxpc3QxOCgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGVMaXN0MTggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZERvdWJsZUxpc3QxOChkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8uYWRkRG91YmxlKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZERvdWJsZUxpc3QxOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRG91YmxlTGlzdDE4KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGREb3VibGVMaXN0MTgoKSB7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEZsb2F0TGlzdDE5Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZsb2F0TGlzdDE5Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGbG9hdExpc3QxOV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKSB7CiAgICAgICAgZmllbGRGbG9hdExpc3QxOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdDE5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdDE5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZsb2F0TGlzdDE5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3QxOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZsb2F0TGlzdDE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdExpc3QxOSgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdExpc3QxOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRmxvYXRMaXN0MTkoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLmFkZEZsb2F0KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRGbG9hdExpc3QxOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRmxvYXRMaXN0MTkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEZsb2F0TGlzdDE5Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdExpc3QxOSgpIHsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRJbnQ2NExpc3QyMF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkSW50NjRMaXN0MjBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpIHsKICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50NjRMaXN0MjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdDIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjRMaXN0MjAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0TGlzdDIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NExpc3QyMCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjRMaXN0MjAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEludDY0TGlzdDIwKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEludDY0TGlzdDIwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRJbnQ2NExpc3QyMCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0MjBJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRJbnQ2NExpc3QyMF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50NjRMaXN0MjAoKSB7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRVaW50NjRMaXN0MjFfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFVpbnQ2NExpc3QyMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFVpbnQ2NExpc3QyMV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpIHsKICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3QyMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NExpc3QyMShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0TGlzdDIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjRMaXN0MjEoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjRMaXN0MjEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFVpbnQ2NExpc3QyMShsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkVWludDY0TGlzdDIxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRVaW50NjRMaXN0MjEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFVpbnQ2NExpc3QyMV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50NjRMaXN0MjEoKSB7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEludDMyTGlzdDIyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRJbnQzMkxpc3QyMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQzMkxpc3QyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkgewogICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0MjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdDIyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyTGlzdDIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMkxpc3QyMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyTGlzdDIyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRJbnQzMkxpc3QyMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3QyMklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkSW50MzJMaXN0MjIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEludDMyTGlzdDIyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3QyMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEludDMyTGlzdDIyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMkxpc3QyMigpIHsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkRml4ZWQ2NExpc3QyM18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkNjRMaXN0MjNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQ2NExpc3QyM18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQ2NExpc3QyM18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDY0TGlzdDIzXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKSB7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NExpc3QyMyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdDIzXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQ2NExpc3QyMygKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGaXhlZDY0TGlzdDIzKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRml4ZWQ2NExpc3QyMygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEZpeGVkNjRMaXN0MjNfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDY0TGlzdDIzKCkgewogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEZpeGVkMzJMaXN0MjRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkMzJMaXN0MjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQzMkxpc3QyNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQzMkxpc3QyNF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDMyTGlzdDI0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQzMkxpc3QyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKSB7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQzMkxpc3QyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkMzJMaXN0MjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZpeGVkMzJMaXN0MjQoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRml4ZWQzMkxpc3QyNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRml4ZWQzMkxpc3QyNCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDMyTGlzdDI0KCkgewogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRCb29sTGlzdDI1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJvb2xMaXN0MjVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEJvb2xMaXN0MjVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkQm9vbExpc3QyNV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJvb2xMaXN0MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkgewogICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkQm9vbExpc3QyNUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3QyNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0MjUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3QyNV8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2xMaXN0MjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJvb2xMaXN0MjUoCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCb29sTGlzdDI1Xy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbExpc3QyNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkQm9vbExpc3QyNShib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEJvb2xMaXN0MjUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEJvb2xMaXN0MjUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQm9vbExpc3QyNSgpIHsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTdHJpbmdMaXN0MjZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KGZpZWxkU3RyaW5nTGlzdDI2Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRGaWVsZFN0cmluZ0xpc3QyNkxpc3QoKSB7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU3RyaW5nTGlzdDI2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmdMaXN0MjYoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTdHJpbmdMaXN0MjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFN0cmluZ0xpc3QyNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTdHJpbmdMaXN0MjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFN0cmluZ0xpc3QyNigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFN0cmluZ0xpc3QyNl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmdMaXN0MjYoKSB7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFN0cmluZ0xpc3QyNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBmaWVsZE1lc3NhZ2VMaXN0MjdfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCBmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1lc3NhZ2VMaXN0MjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWVzc2FnZUxpc3QyNyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEJ5dGVzTGlzdDI4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCeXRlc0xpc3QyOF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCeXRlc0xpc3QyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpIHsKICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkQnl0ZXNMaXN0MjhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkQnl0ZXNMaXN0MjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzTGlzdDI4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlc0xpc3QyOChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCeXRlc0xpc3QyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQnl0ZXNMaXN0MjgoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQnl0ZXNMaXN0MjggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEJ5dGVzTGlzdDI4KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkQnl0ZXNMaXN0MjggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEJ5dGVzTGlzdDI4KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRCeXRlc0xpc3QyOF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQnl0ZXNMaXN0MjgoKSB7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdDI5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFVpbnQzMkxpc3QyOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQzMkxpc3QyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpIHsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3QyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDMyTGlzdDI5KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkVWludDMyTGlzdDI5KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkVWludDMyTGlzdDI5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRVaW50MzJMaXN0MjkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzJMaXN0MjkoKSB7CiAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0MzBfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihmaWVsZEVudW1MaXN0MzBfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdDMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3QzMExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdDMwXywgZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3QzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0MzBfY29udmVydGVyXy5jb252ZXJ0KGZpZWxkRW51bUxpc3QzMF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3QzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bUxpc3QzMCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdDMwXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3QzMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3QzMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRFbnVtTGlzdDMwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdDMwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEVudW1MaXN0MzAoKSB7CiAgICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0MzFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0MzFfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3QzMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyTGlzdDMxKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNmaXhlZDMyTGlzdDMxKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQzMkxpc3QzMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkMzJMaXN0MzEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkMzJMaXN0MzFfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyTGlzdDMxKCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0MzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjRMaXN0MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQ2NExpc3QzMihsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkNjRMaXN0MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkNjRMaXN0MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0TGlzdDMyKCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0MzNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDMyTGlzdDMzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdDMzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdDMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzJMaXN0MzMoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdDMzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTaW50MzJMaXN0MzMoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50MzJMaXN0MzMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQzMkxpc3QzMygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMkxpc3QzMygpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDY0TGlzdDM0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDY0TGlzdDM0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdDM0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3QzNENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdDM0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdDM0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0MzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NExpc3QzNCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NExpc3QzNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDY0TGlzdDM0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50NjRMaXN0MzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQ2NExpc3QzNCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDY0TGlzdDM0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NExpc3QzNCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGREb3VibGVMaXN0UGFja2VkMzVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGVMaXN0UGFja2VkMzUoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGREb3VibGVMaXN0UGFja2VkMzUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZERvdWJsZUxpc3RQYWNrZWQzNSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGREb3VibGVMaXN0UGFja2VkMzVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkgewogICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRmxvYXRMaXN0UGFja2VkMzYoKSB7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEludDY0TGlzdFBhY2tlZDM3Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKSB7CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjRMaXN0UGFja2VkMzcoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRJbnQ2NExpc3RQYWNrZWQzNyhsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkSW50NjRMaXN0UGFja2VkMzcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0TGlzdFBhY2tlZDM3KCkgewogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRVaW50NjRMaXN0UGFja2VkMzhfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOExpc3QoKSB7CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzgoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRVaW50NjRMaXN0UGFja2VkMzgobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0TGlzdFBhY2tlZDM4KCkgewogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkSW50MzJMaXN0UGFja2VkMzlfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpIHsKICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzJMaXN0UGFja2VkMzkoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkSW50MzJMaXN0UGFja2VkMzkoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRJbnQzMkxpc3RQYWNrZWQzOSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzJMaXN0UGFja2VkMzkoKSB7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCgpIHsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSgpIHsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCb29sTGlzdFBhY2tlZDQyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRCb29sTGlzdFBhY2tlZDQyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJvb2xMaXN0UGFja2VkNDJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpIHsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2xMaXN0UGFja2VkNDIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2xMaXN0UGFja2VkNDIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEJvb2xMaXN0UGFja2VkNDIoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRCb29sTGlzdFBhY2tlZDQyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2xMaXN0UGFja2VkNDIoKSB7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpIHsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRVaW50MzJMaXN0UGFja2VkNDMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzJMaXN0UGFja2VkNDMoKSB7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0UGFja2VkNDRfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihmaWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdFBhY2tlZDQ0XywgZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXy5jb252ZXJ0KGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bUxpc3RQYWNrZWQ0NCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3RQYWNrZWQ0NChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdFBhY2tlZDQ0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEVudW1MaXN0UGFja2VkNDQoKSB7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nihsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IGZpZWxkR3JvdXA0OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OU9yQnVpbGRlcj4gZmllbGRHcm91cDQ5QnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkZ3JvdXA0OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEdyb3VwNDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZGdyb3VwNDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkgZ2V0RmllbGRHcm91cDQ5KCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNDlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRHcm91cDQ5XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEdyb3VwNDlfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRHcm91cDQ5QnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkR3JvdXA0OShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNDlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkR3JvdXA0OV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cDQ5QnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkR3JvdXA0OSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkR3JvdXA0OV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cDQ5QnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRHcm91cDQ5KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5IHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZEdyb3VwNDlfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRHcm91cDQ5XyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRGaWVsZEdyb3VwNDlCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkR3JvdXA0OV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cDQ5QnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEdyb3VwNDkoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGZpZWxkR3JvdXA0OV8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEdyb3VwNDlCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5LkJ1aWxkZXIgZ2V0RmllbGRHcm91cDQ5QnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkR3JvdXA0OUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwNDlPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5LmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRHcm91cDQ5XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNDlPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRHcm91cDQ5RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNDlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDQ5LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA0OU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkR3JvdXA0OSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRHcm91cDQ5XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTE+IGZpZWxkR3JvdXBMaXN0NTFfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxPihmaWVsZEdyb3VwTGlzdDUxXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXI+IGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTE+IGdldEZpZWxkR3JvdXBMaXN0NTFMaXN0KCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkR3JvdXBMaXN0NTFfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkR3JvdXBMaXN0NTFDb3VudCgpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSBnZXRGaWVsZEdyb3VwTGlzdDUxKGludCBpbmRleCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkR3JvdXBMaXN0NTEoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEdyb3VwTGlzdDUxKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkR3JvdXBMaXN0NTEoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEdyb3VwTGlzdDUxKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRHcm91cExpc3Q1MSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkR3JvdXBMaXN0NTEoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRHcm91cExpc3Q1MSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxPiB2YWx1ZXMpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIGZpZWxkR3JvdXBMaXN0NTFfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEdyb3VwTGlzdDUxKCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkR3JvdXBMaXN0NTEoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLkJ1aWxkZXIgZ2V0RmllbGRHcm91cExpc3Q1MUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRHcm91cExpc3Q1MUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIgZ2V0RmllbGRHcm91cExpc3Q1MU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXI+IAogICAgICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLkJ1aWxkZXIgYWRkRmllbGRHcm91cExpc3Q1MUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkR3JvdXBMaXN0NTFGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciBhZGRGaWVsZEdyb3VwTGlzdDUxQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZEdyb3VwTGlzdDUxRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRGaWVsZEdyb3VwTGlzdDUxQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkR3JvdXBMaXN0NTFGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwTGlzdDUxLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDIwMDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXzsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGREb3VibGU1MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTUzKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1MzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV81MyA9IDUzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGU1My4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGU1MygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTMpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkRvdWJsZSkgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBEOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlNTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZERvdWJsZTUzKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDUzOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV81MyA9IDUzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZERvdWJsZTUzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZsb2F0NTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGbG9hdDU0KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQ1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0NTQoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5GbG9hdCkgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBGOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZsb2F0NTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZsb2F0NTQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NDsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRmxvYXQ1NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTQpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQ2NDU1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQ1NSgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0NTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0NTUoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEw7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjQ1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjQ1NShsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTU7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0NTUoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50NjQ1NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQ2NDU2KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQ1Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0NTYoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEw7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjQ1NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0NTYobG9uZyB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU2OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQ2NDU2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NikgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjU3KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjU3KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzI1NyhpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NzsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI1NygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTcpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQ2NDU4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQ2NDU4KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1ODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NDU4KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OCkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDY0NTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjQ1OChsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTg7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDY0NTgoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI1OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMjU5KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkMzI1OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQzMjU5KGludCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU5OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMjU5KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OSkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sNjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCb29sNjAoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbDYwLgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sNjAoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYwKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Cb29sZWFuKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2w2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQm9vbDYwKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MDsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2w2MCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFN0cmluZzYxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTdHJpbmc2MSgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nNjEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nNjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHJlZiA9IHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzYxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRGaWVsZFN0cmluZzYxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHJlZiA9IHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTdHJpbmc2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU3RyaW5nNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYxOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFN0cmluZzYxKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzYxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjE7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IGZpZWxkTWVzc2FnZTYyQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1lc3NhZ2U2MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTYyKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTYyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB0ZXN0T25lb2ZfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlNjIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlNjIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgdGVzdE9uZW9mXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZE1lc3NhZ2U2Mihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyICYmCiAgICAgICAgICAgICAgdGVzdE9uZW9mXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHRlc3RPbmVvZl8pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWVzc2FnZTYyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlNjJCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2U2MkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTYyT3JCdWlsZGVyKCkgewogICAgICAgIGlmICgodGVzdE9uZW9mQ2FzZV8gPT0gNjIpICYmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHRlc3RPbmVvZl87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTYyRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKHRlc3RPbmVvZkNhc2VfID09IDYyKSkgewogICAgICAgICAgICB0ZXN0T25lb2ZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdGVzdE9uZW9mXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXM2MygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXM2MygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzNjMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYzOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCeXRlczYzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyNjQoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NDsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzI2NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyNjUoaW50IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjU7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyNjUoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkNjQ2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDY2LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDY2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0NjYobG9uZyB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY2OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQ2NDY2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzI2NygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjc7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyNjcoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY3KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMjY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzI2NyhpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NzsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzI2NygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0NjgoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQ2OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NDY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjQ2OChsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjg7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDY0NjgoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjksIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5T3JCdWlsZGVyPiBmaWVsZEdyb3VwNjlCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRncm91cDY5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRHcm91cDY5KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2OTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRncm91cDY5LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgZ2V0RmllbGRHcm91cDY5KCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNjlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjkpIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSkgdGVzdE9uZW9mXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNjlCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRHcm91cDY5KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5IHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA2OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXA2OUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY5OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRHcm91cDY5KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cDY5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgdGVzdE9uZW9mXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXA2OUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY5OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZEdyb3VwNjkoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cDY5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5ICYmCiAgICAgICAgICAgICAgdGVzdE9uZW9mXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICB0ZXN0T25lb2ZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkpIHRlc3RPbmVvZl8pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjkpIHsKICAgICAgICAgICAgZmllbGRHcm91cDY5QnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkR3JvdXA2OUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY5OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEdyb3VwNjkoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA2OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZEdyb3VwNjlCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5CdWlsZGVyIGdldEZpZWxkR3JvdXA2OUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkR3JvdXA2OUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5T3JCdWlsZGVyIGdldEZpZWxkR3JvdXA2OU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKHRlc3RPbmVvZkNhc2VfID09IDY5KSAmJiAoZmllbGRHcm91cDY5QnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNjlCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5KSB0ZXN0T25lb2ZfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZEdyb3VwNjlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA2OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKHRlc3RPbmVvZkNhc2VfID09IDY5KSkgewogICAgICAgICAgICB0ZXN0T25lb2ZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZEdyb3VwNjlCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRHcm91cDY5LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkR3JvdXA2OSkgdGVzdE9uZW9mXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY5OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZEdyb3VwNjlCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBkb3VibGUgZmllbGRSZXF1aXJlZERvdWJsZTcxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBkb3VibGUgZmllbGRfcmVxdWlyZWRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWREb3VibGU3MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWREb3VibGU3MS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWREb3VibGU3MV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZERvdWJsZTcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZERvdWJsZTcxKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkRG91YmxlNzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBkb3VibGUgZmllbGRfcmVxdWlyZWRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWREb3VibGU3MSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgZmllbGRSZXF1aXJlZERvdWJsZTcxXyA9IDBEOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IGZpZWxkUmVxdWlyZWRGbG9hdDcyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmbG9hdCBmaWVsZF9yZXF1aXJlZF9mbG9hdF83MiA9IDcyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRmxvYXQ3MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZmxvYXQgZmllbGRfcmVxdWlyZWRfZmxvYXRfNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRGbG9hdDcyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRSZXF1aXJlZEZsb2F0NzIoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRGbG9hdDcyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZmxvYXQgZmllbGRfcmVxdWlyZWRfZmxvYXRfNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEZsb2F0NzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MihmbG9hdCB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZsb2F0IGZpZWxkX3JlcXVpcmVkX2Zsb2F0XzcyID0gNzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRGbG9hdDcyKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml8gPSAwRjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRJbnQ2NDczXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQ2NCBmaWVsZF9yZXF1aXJlZF9pbnQ2NF83MyA9IDczOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkSW50NjQ3MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50NjQgZmllbGRfcmVxdWlyZWRfaW50NjRfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRJbnQ2NDczLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkSW50NjQ3MygpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEludDY0NzNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQ2NCBmaWVsZF9yZXF1aXJlZF9pbnQ2NF83MyA9IDczOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkSW50NjQ3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRJbnQ2NDczKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZEludDY0NzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQ2NCBmaWVsZF9yZXF1aXJlZF9pbnQ2NF83MyA9IDczOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkSW50NjQ3MygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZEludDY0NzNfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZFJlcXVpcmVkVWludDY0NzRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQ2NCBmaWVsZF9yZXF1aXJlZF91aW50NjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkVWludDY0NzQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQ2NCBmaWVsZF9yZXF1aXJlZF91aW50NjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZFVpbnQ2NDc0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZFVpbnQ2NDc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkVWludDY0NzQoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZEludDMyNzVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGZpZWxkX3JlcXVpcmVkX2ludDMyXzc1ID0gNzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRJbnQzMjc1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBmaWVsZF9yZXF1aXJlZF9pbnQzMl83NSA9IDc1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEludDMyNzUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZEludDMyNzUoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRJbnQzMjc1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgZmllbGRfcmVxdWlyZWRfaW50MzJfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEludDMyNzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkSW50MzI3NShpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZEludDMyNzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBmaWVsZF9yZXF1aXJlZF9pbnQzMl83NSA9IDc1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkSW50MzI3NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgZmllbGRSZXF1aXJlZEludDMyNzVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkNjQgZmllbGRfcmVxdWlyZWRfZml4ZWQ2NF83NiA9IDc2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkNjQgZmllbGRfcmVxdWlyZWRfZml4ZWQ2NF83NiA9IDc2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Ni4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkNjQgZmllbGRfcmVxdWlyZWRfZml4ZWQ2NF83NiA9IDc2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZEZpeGVkNjQ3Nihsb25nIHZhbHVlKSB7CgogICAgICAgIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX2ZpeGVkNjRfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZEZpeGVkMzI3N18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9maXhlZDMyXzc3ID0gNzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9maXhlZDMyXzc3ID0gNzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEZpeGVkMzI3NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkMzI3N18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gZmllbGRSZXF1aXJlZEJvb2w3OF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYm9vbCBmaWVsZF9yZXF1aXJlZF9ib29sXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRCb29sNzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYm9vbCBmaWVsZF9yZXF1aXJlZF9ib29sXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkQm9vbDc4LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZFJlcXVpcmVkQm9vbDc4KCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkQm9vbDc4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYm9vbCBmaWVsZF9yZXF1aXJlZF9ib29sXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRCb29sNzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkQm9vbDc4KGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZEJvb2w3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJvb2wgZmllbGRfcmVxdWlyZWRfYm9vbF83OCA9IDc4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkQm9vbDc4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkQm9vbDc4XyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkU3RyaW5nNzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFN0cmluZzc5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRSZXF1aXJlZFN0cmluZzc5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGRSZXF1aXJlZFN0cmluZzc5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkUmVxdWlyZWRTdHJpbmc3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGRSZXF1aXJlZFN0cmluZzc5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZFN0cmluZzc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZFN0cmluZzc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSB7CiAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpOwogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZmllbGRSZXF1aXJlZFN0cmluZzc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZFN0cmluZzc5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRNZXNzYWdlODAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRNZXNzYWdlODAoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRSZXF1aXJlZE1lc3NhZ2U4MChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApICYmCiAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuUmVxdWlyZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRCeXRlczgxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyBmaWVsZF9yZXF1aXJlZF9ieXRlc184MSA9IDgxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEJ5dGVzODEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRSZXF1aXJlZEJ5dGVzODEoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRCeXRlczgxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgZmllbGRfcmVxdWlyZWRfYnl0ZXNfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEJ5dGVzODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MShjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgZmllbGRfcmVxdWlyZWRfYnl0ZXNfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZEJ5dGVzODEoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEZpZWxkUmVxdWlyZWRCeXRlczgxKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkVWludDMyODIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkVWludDMyODIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50MzIgZmllbGRfcmVxdWlyZWRfdWludDMyXzgyID0gODI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkVWludDMyODIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZFVpbnQzMjgyKCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkVWludDMyODJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50MzIgZmllbGRfcmVxdWlyZWRfdWludDMyXzgyID0gODI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRVaW50MzI4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRVaW50MzI4MihpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZFVpbnQzMjgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkVWludDMyODIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkRW51bTgzXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZmllbGRfcmVxdWlyZWRfZW51bV84MyA9IDgzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkRW51bTgzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEVudW04MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9yZXF1aXJlZF9lbnVtXzgzID0gODM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRW51bTgzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZFJlcXVpcmVkRW51bTgzKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRSZXF1aXJlZEVudW04M18pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEVudW04MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRFbnVtODMoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRFbnVtODNfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9yZXF1aXJlZF9lbnVtXzgzID0gODM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRFbnVtODMoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRFbnVtODNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX3NmaXhlZDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9zZml4ZWQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFNmaXhlZDMyODQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkMzIgZmllbGRfcmVxdWlyZWRfc2ZpeGVkMzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZFNmaXhlZDMyODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NChpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9zZml4ZWQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkNjQgZmllbGRfcmVxdWlyZWRfc2ZpeGVkNjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkUmVxdWlyZWRTaW50MzI4Nl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDMyIGZpZWxkX3JlcXVpcmVkX3NpbnQzMl84NiA9IDg2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkU2ludDMyODYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ludDMyODYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50MzIgZmllbGRfcmVxdWlyZWRfc2ludDMyXzg2ID0gODY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ludDMyODYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZFNpbnQzMjg2KCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkU2ludDMyODZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50MzIgZmllbGRfcmVxdWlyZWRfc2ludDMyXzg2ID0gODY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRTaW50MzI4NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRTaW50MzI4NihpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDMyIGZpZWxkX3JlcXVpcmVkX3NpbnQzMl84NiA9IDg2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkU2ludDMyODYoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRTaW50MzI4Nl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZFNpbnQ2NDg3XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50NjQgZmllbGRfcmVxdWlyZWRfc2ludDY0Xzg3ID0gODc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTaW50NjQ4NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRTaW50NjQ4NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTaW50NjQ4Ny4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkU2ludDY0ODdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50NjQgZmllbGRfcmVxdWlyZWRfc2ludDY0Xzg3ID0gODc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRTaW50NjQ4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRTaW50NjQ4Nyhsb25nIHZhbHVlKSB7CgogICAgICAgIGZpZWxkUmVxdWlyZWRTaW50NjQ4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkU2ludDY0ODdfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODguQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlcj4gZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZHJlcXVpcmVkZ3JvdXA4OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRyZXF1aXJlZGdyb3VwODguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEdyb3VwODhfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4LmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRSZXF1aXJlZEdyb3VwODhfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkR3JvdXA4OChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODguQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkUmVxdWlyZWRHcm91cDg4KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODggdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDJfICYgMHgwMDEwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODguZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkR3JvdXA4OF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRHcm91cDg4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkUmVxdWlyZWRHcm91cDg4XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuRmllbGRSZXF1aXJlZEdyb3VwODguQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkZpZWxkUmVxdWlyZWRHcm91cDg4T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODgoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMk1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8yTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMk1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMk1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBQcm90bzJFbXB0eU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yRW1wdHkpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJFbXB0eX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvMkVtcHR5IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJFbXB0eSkKICAgICAgUHJvdG8yRW1wdHlPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvMkVtcHR5Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFByb3RvMkVtcHR5KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUHJvdG8yRW1wdHkoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUHJvdG8yRW1wdHkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMkVtcHR5X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJFbXB0eV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMkVtcHR5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMkVtcHR5KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yRW1wdHlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJFbXB0eV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yRW1wdHlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMkVtcHR5KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yRW1wdHkpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJFbXB0eSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yRW1wdHkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJFbXB0eT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzJFbXB0eT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMkVtcHR5IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yRW1wdHk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yRW1wdHk+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMkVtcHR5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8UHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zPiB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnM+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zKQogICAgICBQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucz4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoMTAwMDEsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucykKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEZpZWxkR3JvdXA0OU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwuRmllbGRHcm91cDQ5KQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjUwKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5GaWVsZEdyb3VwNDl9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZEdyb3VwNDkgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLkZpZWxkR3JvdXA0OSkKICAgICAgRmllbGRHcm91cDQ5T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGaWVsZEdyb3VwNDkubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRmllbGRHcm91cDQ5KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRmllbGRHcm91cDQ5KCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZpZWxkR3JvdXA0OSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cDQ5X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwNDlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNTBfRklFTERfTlVNQkVSID0gNTA7CiAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTBfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTAoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyNTBfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNTAsIGZpZWxkSW50MzI1MF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUwLCBmaWVsZEludDMyNTBfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkpIG9iajsKCiAgICAgIGlmIChoYXNGaWVsZEludDMyNTAoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyNTAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRJbnQzMjUwKCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRJbnQzMjUwKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjUwKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGaWVsZEludDMyNTAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzUwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNTAoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLkZpZWxkR3JvdXA0OX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5GaWVsZEdyb3VwNDkpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cDQ5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cDQ5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5Lm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBmaWVsZEludDMyNTBfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI1MF8gPSBmaWVsZEludDMyNTBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkSW50MzI1MCgpKSB7CiAgICAgICAgICBzZXRGaWVsZEludDMyNTAob3RoZXIuZ2V0RmllbGRJbnQzMjUwKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDQwMDogewogICAgICAgICAgICAgICAgZmllbGRJbnQzMjUwXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTBfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUwKCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyNTBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyNTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyNTAoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkSW50MzI1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZmllbGRJbnQzMjUwXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLkZpZWxkR3JvdXA0OSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLkZpZWxkR3JvdXA0OSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA0OT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGaWVsZEdyb3VwNDk+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBGaWVsZEdyb3VwNDkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwNDk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cDQ5PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5GaWVsZEdyb3VwTGlzdDUxKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjUyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5GaWVsZEdyb3VwTGlzdDUxfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRHcm91cExpc3Q1MSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuRmllbGRHcm91cExpc3Q1MSkKICAgICAgRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgRmllbGRHcm91cExpc3Q1MS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGaWVsZEdyb3VwTGlzdDUxKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRmllbGRHcm91cExpc3Q1MSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBGaWVsZEdyb3VwTGlzdDUxKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwTGlzdDUxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNTJfRklFTERfTlVNQkVSID0gNTI7CiAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTIoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyNTJfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNTIsIGZpZWxkSW50MzI1Ml8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUyLCBmaWVsZEludDMyNTJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEpIG9iajsKCiAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyNTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRJbnQzMjUyKCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRJbnQzMjUyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjUyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzUyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNTIoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5GaWVsZEdyb3VwTGlzdDUxfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLkZpZWxkR3JvdXBMaXN0NTEpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwTGlzdDUxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBmaWVsZEludDMyNTJfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI1Ml8gPSBmaWVsZEludDMyNTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEludDMyNTIoKSkgewogICAgICAgICAgc2V0RmllbGRJbnQzMjUyKG90aGVyLmdldEZpZWxkSW50MzI1MigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzI1Ml8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMjUyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1MigpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMjUyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjUyKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZEludDMyNTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyNTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkSW50MzI1Ml8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5GaWVsZEdyb3VwTGlzdDUxKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuRmllbGRHcm91cExpc3Q1MSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXBMaXN0NTE+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RmllbGRHcm91cExpc3Q1MT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEZpZWxkR3JvdXBMaXN0NTEgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwTGlzdDUxPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXBMaXN0NTE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBQcm90bzJNZXNzYWdlV2l0aE1hcHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEJvb2wxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBCb29sQm9vbDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xCeXRlczJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbERvdWJsZTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbERvdWJsZTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBCb29sRG91YmxlMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwQm9vbERvdWJsZTNPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEVudW00KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZsb2F0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sSW50NjQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sVWludDY0MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDMyMzMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEVudW0zOCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJCeXRlczUzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMySW50NjQ2MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyVWludDY0NjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Qm9vbDY5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDY0Qm9vbDY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRCeXRlczcwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjREb3VibGU3MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RW51bTcyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50NjRFbnVtNzJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0SW50NjQ3N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0VWludDMyODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0VWludDY0ODVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMySW50MzI5MygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRFbnVtMTQwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRG91YmxlMTczTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTaW50MzIxODMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEVudW0xOTEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm90bzJNZXNzYWdlV2l0aE1hcHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcykKICAgICAgUHJvdG8yTWVzc2FnZVdpdGhNYXBzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQcm90bzJNZXNzYWdlV2l0aE1hcHMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUHJvdG8yTWVzc2FnZVdpdGhNYXBzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUHJvdG8yTWVzc2FnZVdpdGhNYXBzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvMk1lc3NhZ2VXaXRoTWFwcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKTsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgICAgIGNhc2UgODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpOwogICAgICAgIGNhc2UgOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpOwogICAgICAgIGNhc2UgMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKTsKICAgICAgICBjYXNlIDExOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpOwogICAgICAgIGNhc2UgMTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCk7CiAgICAgICAgY2FzZSAxMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgY2FzZSAxNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCk7CiAgICAgICAgY2FzZSAxNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgY2FzZSAxNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCk7CiAgICAgICAgY2FzZSAxODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpOwogICAgICAgIGNhc2UgMTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAgICAgY2FzZSAyMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCk7CiAgICAgICAgY2FzZSAyMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpOwogICAgICAgIGNhc2UgMjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICBjYXNlIDIzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCk7CiAgICAgICAgY2FzZSAyNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKTsKICAgICAgICBjYXNlIDI1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgIGNhc2UgMjY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCk7CiAgICAgICAgY2FzZSAyNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpOwogICAgICAgIGNhc2UgMjg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCk7CiAgICAgICAgY2FzZSAyOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKTsKICAgICAgICBjYXNlIDMwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKTsKICAgICAgICBjYXNlIDMxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgICAgICBjYXNlIDMyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKTsKICAgICAgICBjYXNlIDMzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgICAgICBjYXNlIDM0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICBjYXNlIDM1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCk7CiAgICAgICAgY2FzZSAzNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKTsKICAgICAgICBjYXNlIDM3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICBjYXNlIDM4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCk7CiAgICAgICAgY2FzZSAzOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgICAgIGNhc2UgNDA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgICAgICBjYXNlIDQxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpOwogICAgICAgIGNhc2UgNDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAgICAgY2FzZSA0MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKTsKICAgICAgICBjYXNlIDQ0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCk7CiAgICAgICAgY2FzZSA0NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKTsKICAgICAgICBjYXNlIDQ2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgICAgIGNhc2UgNDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpOwogICAgICAgIGNhc2UgNDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpOwogICAgICAgIGNhc2UgNDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpOwogICAgICAgIGNhc2UgNTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpOwogICAgICAgIGNhc2UgNTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpOwogICAgICAgIGNhc2UgNTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgY2FzZSA1MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCk7CiAgICAgICAgY2FzZSA1NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgICAgIGNhc2UgNTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgY2FzZSA1NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKTsKICAgICAgICBjYXNlIDU3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpOwogICAgICAgIGNhc2UgNTg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgICAgIGNhc2UgNTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpOwogICAgICAgIGNhc2UgNjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpOwogICAgICAgIGNhc2UgNjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAgICAgY2FzZSA2MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCk7CiAgICAgICAgY2FzZSA2MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCk7CiAgICAgICAgY2FzZSA2NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgIGNhc2UgNjU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKTsKICAgICAgICBjYXNlIDY2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAgICAgY2FzZSA2NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgICAgIGNhc2UgNjg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKTsKICAgICAgICBjYXNlIDY5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpOwogICAgICAgIGNhc2UgNzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgIGNhc2UgNzE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKTsKICAgICAgICBjYXNlIDcyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgICAgIGNhc2UgNzM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCk7CiAgICAgICAgY2FzZSA3NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKTsKICAgICAgICBjYXNlIDc1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKTsKICAgICAgICBjYXNlIDc2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKTsKICAgICAgICBjYXNlIDc3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKTsKICAgICAgICBjYXNlIDc4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpOwogICAgICAgIGNhc2UgNzk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgIGNhc2UgODA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgICAgIGNhc2UgODE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKTsKICAgICAgICBjYXNlIDgyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgY2FzZSA4MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpOwogICAgICAgIGNhc2UgODQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKTsKICAgICAgICBjYXNlIDg1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgY2FzZSA4NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgICAgICBjYXNlIDg3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKTsKICAgICAgICBjYXNlIDg4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgY2FzZSA4OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgICAgICBjYXNlIDkwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpOwogICAgICAgIGNhc2UgOTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAgICAgY2FzZSA5MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCk7CiAgICAgICAgY2FzZSA5MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCk7CiAgICAgICAgY2FzZSA5NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCk7CiAgICAgICAgY2FzZSA5NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKTsKICAgICAgICBjYXNlIDk2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKTsKICAgICAgICBjYXNlIDk3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgICAgICBjYXNlIDk4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAgICAgY2FzZSA5OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgICAgIGNhc2UgMTAwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgIGNhc2UgMTAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpOwogICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpOwogICAgICAgIGNhc2UgMTAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgICAgICBjYXNlIDEwNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgICAgIGNhc2UgMTA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgICAgIGNhc2UgMTA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgICAgICBjYXNlIDEwNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAgICAgY2FzZSAxMDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpOwogICAgICAgIGNhc2UgMTA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAgICAgY2FzZSAxMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgICAgICBjYXNlIDExMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpOwogICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgICAgICBjYXNlIDExMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpOwogICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCk7CiAgICAgICAgY2FzZSAxMTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAgICAgY2FzZSAxMTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCk7CiAgICAgICAgY2FzZSAxMTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCk7CiAgICAgICAgY2FzZSAxMTg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAgICAgY2FzZSAxMTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCk7CiAgICAgICAgY2FzZSAxMjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKTsKICAgICAgICBjYXNlIDEyMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgICAgICBjYXNlIDEyMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCk7CiAgICAgICAgY2FzZSAxMjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgICAgICBjYXNlIDEyNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgICAgIGNhc2UgMTI1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCk7CiAgICAgICAgY2FzZSAxMjY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCk7CiAgICAgICAgY2FzZSAxMjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAgICAgY2FzZSAxMjg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCk7CiAgICAgICAgY2FzZSAxMjk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKTsKICAgICAgICBjYXNlIDEzMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKTsKICAgICAgICBjYXNlIDEzMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKTsKICAgICAgICBjYXNlIDEzMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCk7CiAgICAgICAgY2FzZSAxMzM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpOwogICAgICAgIGNhc2UgMTM0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgICAgICBjYXNlIDEzNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCk7CiAgICAgICAgY2FzZSAxMzY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpOwogICAgICAgIGNhc2UgMTM3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCk7CiAgICAgICAgY2FzZSAxMzg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAgICAgY2FzZSAxMzk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpOwogICAgICAgIGNhc2UgMTQwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCk7CiAgICAgICAgY2FzZSAxNDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKTsKICAgICAgICBjYXNlIDE0MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgIGNhc2UgMTQzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpOwogICAgICAgIGNhc2UgMTQ0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpOwogICAgICAgIGNhc2UgMTQ1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgICAgIGNhc2UgMTQ2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCk7CiAgICAgICAgY2FzZSAxNDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAgICAgY2FzZSAxNDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgY2FzZSAxNDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpOwogICAgICAgIGNhc2UgMTUwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgICAgICBjYXNlIDE1MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAgICAgY2FzZSAxNTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpOwogICAgICAgIGNhc2UgMTUzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgICAgICBjYXNlIDE1NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgIGNhc2UgMTU1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpOwogICAgICAgIGNhc2UgMTU2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgICAgICBjYXNlIDE1NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgIGNhc2UgMTU4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCk7CiAgICAgICAgY2FzZSAxNTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKTsKICAgICAgICBjYXNlIDE2MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKTsKICAgICAgICBjYXNlIDE2MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgICAgICBjYXNlIDE2MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgICAgICBjYXNlIDE2MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpOwogICAgICAgIGNhc2UgMTY0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpOwogICAgICAgIGNhc2UgMTY1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpOwogICAgICAgIGNhc2UgMTY2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgICAgICBjYXNlIDE2NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCk7CiAgICAgICAgY2FzZSAxNjg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgICAgIGNhc2UgMTY5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKTsKICAgICAgICBjYXNlIDE3MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCk7CiAgICAgICAgY2FzZSAxNzE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKTsKICAgICAgICBjYXNlIDE3MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICBjYXNlIDE3MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCk7CiAgICAgICAgY2FzZSAxNzQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKTsKICAgICAgICBjYXNlIDE3NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpOwogICAgICAgIGNhc2UgMTc2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAgICAgY2FzZSAxNzc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCk7CiAgICAgICAgY2FzZSAxNzg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCk7CiAgICAgICAgY2FzZSAxNzk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCk7CiAgICAgICAgY2FzZSAxODA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKTsKICAgICAgICBjYXNlIDE4MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICBjYXNlIDE4MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgICAgICBjYXNlIDE4MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCk7CiAgICAgICAgY2FzZSAxODQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgIGNhc2UgMTg1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKTsKICAgICAgICBjYXNlIDE4NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCk7CiAgICAgICAgY2FzZSAxODc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgIGNhc2UgMTg4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAgICAgY2FzZSAxODk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCk7CiAgICAgICAgY2FzZSAxOTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgIGNhc2UgMTkxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAgICAgY2FzZSAxOTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKTsKICAgICAgICBjYXNlIDE5MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgICAgIGNhc2UgMTk0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgICAgIGNhc2UgMTk1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpOwogICAgICAgIGNhc2UgMTk2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgIGNhc2UgMTk3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCk7CiAgICAgICAgY2FzZSAxOTg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCk7CiAgICAgICAgY2FzZSAxOTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAgICAgY2FzZSAyMDA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKTsKICAgICAgICBjYXNlIDIwMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgY2FzZSAyMDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpOwogICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfQk9PTF8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEJvb2wxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xCb29sMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0JZVEVTXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQnl0ZXMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEJvb2xCeXRlczJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEJ5dGVzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xCeXRlczJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xCeXRlczJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9ET1VCTEVfM19GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xEb3VibGUzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBCb29sRG91YmxlM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xEb3VibGUzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xEb3VibGUzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRG91YmxlM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEJvb2xEb3VibGUzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0VOVU1fNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEVudW00XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sRW51bTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xFbnVtNF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xFbnVtNCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZJWEVEMzJfNV9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sRml4ZWQ2NDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9GTE9BVF83X0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZsb2F0N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9JTlQzMl84X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEludDMyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sSW50NjQ5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDY0OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDY0OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfTUVTU0FHRV8xMF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0ZJWEVEMzJfMTFfRklFTERfTlVNQkVSID0gMTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkNjQxMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1NJTlQzMl8xM19GSUVMRF9OVU1CRVIgPSAxMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xTaW50MzIxM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDMyMTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQzMjEzKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1NJTlQ2NF8xNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDY0MTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50NjQxNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9TVFJJTkdfMTVfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTdHJpbmcxNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1VJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1VJTlQ2NF8xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDY0MTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sVWludDY0MTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDY0MTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCb29sMThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVIgPSAxOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCeXRlczE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9ET1VCTEVfMjBfRklFTERfTlVNQkVSID0gMjA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfRU5VTV8yMV9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9GSVhFRDMyXzIyX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVENjRfMjNfRklFTERfTlVNQkVSID0gMjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZMT0FUXzI0X0ZJRUxEX05VTUJFUiA9IDI0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfSU5UMzJfMjVfRklFTERfTlVNQkVSID0gMjU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJJbnQzMjI1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9JTlQ2NF8yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUiA9IDI3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDMyXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfU0ZJWEVENjRfMjlfRklFTERfTlVNQkVSID0gMjk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfU0lOVDMyXzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TSU5UNjRfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSID0gMzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfVUlOVDMyXzMzX0ZJRUxEX05VTUJFUiA9IDMzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9VSU5UNjRfMzRfRklFTERfTlVNQkVSID0gMzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJVaW50NjQzNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9CT09MXzM1X0ZJRUxEX05VTUJFUiA9IDM1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qm9vbDM1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfQllURVNfMzZfRklFTERfTlVNQkVSID0gMzY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0RPVUJMRV8zN19GSUVMRF9OVU1CRVIgPSAzNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRklYRUQzMl8zOV9GSUVMRF9OVU1CRVIgPSAzOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRklYRUQ2NF80MF9GSUVMRF9OVU1CRVIgPSA0MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0ZMT0FUXzQxX0ZJRUxEX05VTUJFUiA9IDQxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0lOVDMyXzQyX0ZJRUxEX05VTUJFUiA9IDQyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0lOVDY0XzQzX0ZJRUxEX05VTUJFUiA9IDQzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9NRVNTQUdFXzQ0X0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQzMl80NV9GSUVMRF9OVU1CRVIgPSA0NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQ2NF80Nl9GSUVMRF9OVU1CRVIgPSA0NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfU0lOVDMyXzQ3X0ZJRUxEX05VTUJFUiA9IDQ3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ludDMyNDdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfU0lOVDY0XzQ4X0ZJRUxEX05VTUJFUiA9IDQ4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50NjQ0OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NUUklOR180OV9GSUVMRF9OVU1CRVIgPSA0OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfVUlOVDMyXzUwX0ZJRUxEX05VTUJFUiA9IDUwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50MzI1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfVUlOVDY0XzUxX0ZJRUxEX05VTUJFUiA9IDUxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9CT09MXzUyX0ZJRUxEX05VTUJFUiA9IDUyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkJvb2w1MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwSW50MzJCb29sNTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJCb29sNTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCb29sNTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJvb2w1MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9CWVRFU181M19GSUVMRF9OVU1CRVIgPSA1MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJCeXRlczUzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBJbnQzMkJ5dGVzNTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkJ5dGVzNTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJCeXRlczUzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9ET1VCTEVfNTRfRklFTERfTlVNQkVSID0gNTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkRvdWJsZTU0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkRvdWJsZTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJEb3VibGU1NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJEb3VibGU1NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfRU5VTV81NV9GSUVMRF9OVU1CRVIgPSA1NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRW51bTU1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkVudW01NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJFbnVtNTUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDMyRW51bTU1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9GSVhFRDMyXzU2X0ZJRUxEX05VTUJFUiA9IDU2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0ZJWEVENjRfNTdfRklFTERfTlVNQkVSID0gNTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0ZMT0FUXzU4X0ZJRUxEX05VTUJFUiA9IDU4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGbG9hdDU4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwSW50MzJGbG9hdDU4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJGbG9hdDU4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfSU5UMzJfNTlfRklFTERfTlVNQkVSID0gNTk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMySW50MzI1OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDMyNTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9JTlQ2NF82MF9GSUVMRF9OVU1CRVIgPSA2MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMySW50NjQ2MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50NjQ2MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9NRVNTQUdFXzYxX0ZJRUxEX05VTUJFUiA9IDYxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyTWVzc2FnZTYxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyTWVzc2FnZTYxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1NGSVhFRDMyXzYyX0ZJRUxEX05VTUJFUiA9IDYyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVENjRfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0lOVDMyXzY0X0ZJRUxEX05VTUJFUiA9IDY0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlNpbnQzMjY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50MzI2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TSU5UNjRfNjVfRklFTERfTlVNQkVSID0gNjU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TVFJJTkdfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfVUlOVDMyXzY3X0ZJRUxEX05VTUJFUiA9IDY3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlVpbnQzMjY3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50MzI2N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9VSU5UNjRfNjhfRklFTERfTlVNQkVSID0gNjg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9CT09MXzY5X0ZJRUxEX05VTUJFUiA9IDY5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDY0Qm9vbDY5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0Qm9vbDY5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qm9vbDY5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfQllURVNfNzBfRklFTERfTlVNQkVSID0gNzA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0Qnl0ZXM3MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0RPVUJMRV83MV9GSUVMRF9OVU1CRVIgPSA3MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjREb3VibGU3MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRU5VTV83Ml9GSUVMRF9OVU1CRVIgPSA3MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRFbnVtNzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RW51bTcyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDY0RW51bTcyTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRklYRUQzMl83M19GSUVMRF9OVU1CRVIgPSA3MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0Rml4ZWQzMjczXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRklYRUQ2NF83NF9GSUVMRF9OVU1CRVIgPSA3NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0ZMT0FUXzc1X0ZJRUxEX05VTUJFUiA9IDc1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0RmxvYXQ3NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0lOVDMyXzc2X0ZJRUxEX05VTUJFUiA9IDc2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRJbnQzMjc2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDMyNzZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0lOVDY0Xzc3X0ZJRUxEX05VTUJFUiA9IDc3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0SW50NjQ3N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQ2NDc3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50NjQ3N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9NRVNTQUdFXzc4X0ZJRUxEX05VTUJFUiA9IDc4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRNZXNzYWdlNzgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TRklYRUQzMl83OV9GSUVMRF9OVU1CRVIgPSA3OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TRklYRUQ2NF84MF9GSUVMRF9OVU1CRVIgPSA4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfU0lOVDMyXzgxX0ZJRUxEX05VTUJFUiA9IDgxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDMyODFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfU0lOVDY0XzgyX0ZJRUxEX05VTUJFUiA9IDgyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVIgPSA4MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBJbnQ2NFN0cmluZzgzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfVUlOVDMyXzg0X0ZJRUxEX05VTUJFUiA9IDg0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NFVpbnQzMjg0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0VWludDMyODRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFVpbnQzMjg0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfVUlOVDY0Xzg1X0ZJRUxEX05VTUJFUiA9IDg1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0JPT0xfODZfRklFTERfTlVNQkVSID0gODY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0JZVEVTXzg3X0ZJRUxEX05VTUJFUiA9IDg3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0RPVUJMRV84OF9GSUVMRF9OVU1CRVIgPSA4ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUiA9IDg5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0ZJWEVEMzJfOTBfRklFTERfTlVNQkVSID0gOTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRkxPQVRfOTJfRklFTERfTlVNQkVSID0gOTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9JTlQzMl85M19GSUVMRF9OVU1CRVIgPSA5MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUiA9IDk0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX01FU1NBR0VfOTVfRklFTERfTlVNQkVSID0gOTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0ZJWEVEMzJfOTZfRklFTERfTlVNQkVSID0gOTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQ2NF85N19GSUVMRF9OVU1CRVIgPSA5NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TSU5UMzJfOThfRklFTERfTlVNQkVSID0gOTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX1NJTlQ2NF85OV9GSUVMRF9OVU1CRVIgPSA5OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX1NUUklOR18xMDBfRklFTERfTlVNQkVSID0gMTAwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9VSU5UMzJfMTAxX0ZJRUxEX05VTUJFUiA9IDEwMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX1VJTlQ2NF8xMDJfRklFTERfTlVNQkVSID0gMTAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X0JPT0xfMTAzX0ZJRUxEX05VTUJFUiA9IDEwMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9CWVRFU18xMDRfRklFTERfTlVNQkVSID0gMTA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfRE9VQkxFXzEwNV9GSUVMRF9OVU1CRVIgPSAxMDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9FTlVNXzEwNl9GSUVMRF9OVU1CRVIgPSAxMDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDMyXzEwN19GSUVMRF9OVU1CRVIgPSAxMDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVIgPSAxMDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfRkxPQVRfMTA5X0ZJRUxEX05VTUJFUiA9IDEwOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UMzJfMTEwX0ZJRUxEX05VTUJFUiA9IDExMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUiA9IDExMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X01FU1NBR0VfMTEyX0ZJRUxEX05VTUJFUiA9IDExMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDMyXzExM19GSUVMRF9OVU1CRVIgPSAxMTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDY0XzExNF9GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UMzJfMTE1X0ZJRUxEX05VTUJFUiA9IDExNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UNjRfMTE2X0ZJRUxEX05VTUJFUiA9IDExNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfU1RSSU5HXzExN19GSUVMRF9OVU1CRVIgPSAxMTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UMzJfMTE4X0ZJRUxEX05VTUJFUiA9IDExODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UNjRfMTE5X0ZJRUxEX05VTUJFUiA9IDExOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUiA9IDEyMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJvb2wxMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVIgPSAxMjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0RPVUJMRV8xMjJfRklFTERfTlVNQkVSID0gMTIyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9FTlVNXzEyM19GSUVMRF9OVU1CRVIgPSAxMjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRW51bTEyM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0ZJWEVEMzJfMTI0X0ZJRUxEX05VTUJFUiA9IDEyNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRklYRUQ2NF8xMjVfRklFTERfTlVNQkVSID0gMTI1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRkxPQVRfMTI2X0ZJRUxEX05VTUJFUiA9IDEyNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGbG9hdDEyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9JTlQzMl8xMjdfRklFTERfTlVNQkVSID0gMTI3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0lOVDY0XzEyOF9GSUVMRF9OVU1CRVIgPSAxMjg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUiA9IDEyOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVEMzJfMTMwX0ZJRUxEX05VTUJFUiA9IDEzMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9TRklYRUQ2NF8xMzFfRklFTERfTlVNQkVSID0gMTMxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9TSU5UMzJfMTMyX0ZJRUxEX05VTUJFUiA9IDEzMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NJTlQ2NF8xMzNfRklFTERfTlVNQkVSID0gMTMzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSID0gMTM0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9VSU5UMzJfMTM1X0ZJRUxEX05VTUJFUiA9IDEzNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1VJTlQ2NF8xMzZfRklFTERfTlVNQkVSID0gMTM2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0JPT0xfMTM3X0ZJRUxEX05VTUJFUiA9IDEzNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRCb29sMTM3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCb29sMTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qm9vbDEzN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9CWVRFU18xMzhfRklFTERfTlVNQkVSID0gMTM4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRCeXRlczEzOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCeXRlczEzOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfRE9VQkxFXzEzOV9GSUVMRF9OVU1CRVIgPSAxMzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVIgPSAxNDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9GSVhFRDMyXzE0MV9GSUVMRF9OVU1CRVIgPSAxNDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9GSVhFRDY0XzE0Ml9GSUVMRF9OVU1CRVIgPSAxNDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfRkxPQVRfMTQzX0ZJRUxEX05VTUJFUiA9IDE0MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfSU5UMzJfMTQ0X0ZJRUxEX05VTUJFUiA9IDE0NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0SW50MzIxNDREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfSU5UNjRfMTQ1X0ZJRUxEX05VTUJFUiA9IDE0NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X01FU1NBR0VfMTQ2X0ZJRUxEX05VTUJFUiA9IDE0NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDMyXzE0N19GSUVMRF9OVU1CRVIgPSAxNDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDY0XzE0OF9GSUVMRF9OVU1CRVIgPSAxNDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9TSU5UMzJfMTQ5X0ZJRUxEX05VTUJFUiA9IDE0OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9TSU5UNjRfMTUwX0ZJRUxEX05VTUJFUiA9IDE1MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU1RSSU5HXzE1MV9GSUVMRF9OVU1CRVIgPSAxNTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9VSU5UMzJfMTUyX0ZJRUxEX05VTUJFUiA9IDE1MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9VSU5UNjRfMTUzX0ZJRUxEX05VTUJFUiA9IDE1MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfQk9PTF8xNTRfRklFTERfTlVNQkVSID0gMTU0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQm9vbDE1NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU3RyaW5nQm9vbDE1NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19CWVRFU18xNTVfRklFTERfTlVNQkVSID0gMTU1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0RPVUJMRV8xNTZfRklFTERfTlVNQkVSID0gMTU2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0VOVU1fMTU3X0ZJRUxEX05VTUJFUiA9IDE1NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19GSVhFRDMyXzE1OF9GSUVMRF9OVU1CRVIgPSAxNTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRklYRUQ2NF8xNTlfRklFTERfTlVNQkVSID0gMTU5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19GTE9BVF8xNjBfRklFTERfTlVNQkVSID0gMTYwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfSU5UMzJfMTYxX0ZJRUxEX05VTUJFUiA9IDE2MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0lOVDY0XzE2Ml9GSUVMRF9OVU1CRVIgPSAxNjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ludDY0MTYyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50NjQxNjIoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfTUVTU0FHRV8xNjNfRklFTERfTlVNQkVSID0gMTYzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NGSVhFRDMyXzE2NF9GSUVMRF9OVU1CRVIgPSAxNjQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSID0gMTY1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NJTlQzMl8xNjZfRklFTERfTlVNQkVSID0gMTY2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TSU5UNjRfMTY3X0ZJRUxEX05VTUJFUiA9IDE2NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NUUklOR18xNjhfRklFTERfTlVNQkVSID0gMTY4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1VJTlQzMl8xNjlfRklFTERfTlVNQkVSID0gMTY5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19VSU5UNjRfMTcwX0ZJRUxEX05VTUJFUiA9IDE3MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nVWludDY0MTcwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUiA9IDE3MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVIgPSAxNzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBVaW50MzJCeXRlczE3Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0RPVUJMRV8xNzNfRklFTERfTlVNQkVSID0gMTczOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRG91YmxlMTczXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRG91YmxlMTczKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9FTlVNXzE3NF9GSUVMRF9OVU1CRVIgPSAxNzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRW51bTE3NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0ZJWEVEMzJfMTc1X0ZJRUxEX05VTUJFUiA9IDE3NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRklYRUQ2NF8xNzZfRklFTERfTlVNQkVSID0gMTc2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRkxPQVRfMTc3X0ZJRUxEX05VTUJFUiA9IDE3NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9JTlQzMl8xNzhfRklFTERfTlVNQkVSID0gMTc4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0lOVDY0XzE3OV9GSUVMRF9OVU1CRVIgPSAxNzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUiA9IDE4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVEMzJfMTgxX0ZJRUxEX05VTUJFUiA9IDE4MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9TRklYRUQ2NF8xODJfRklFTERfTlVNQkVSID0gMTgyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9TSU5UMzJfMTgzX0ZJRUxEX05VTUJFUiA9IDE4MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NJTlQ2NF8xODRfRklFTERfTlVNQkVSID0gMTg0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSID0gMTg1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9VSU5UMzJfMTg2X0ZJRUxEX05VTUJFUiA9IDE4NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDMyMTg2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1VJTlQ2NF8xODdfRklFTERfTlVNQkVSID0gMTg3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDY0MTg3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0JPT0xfMTg4X0ZJRUxEX05VTUJFUiA9IDE4ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRCb29sMTg4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qm9vbDE4OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9CWVRFU18xODlfRklFTERfTlVNQkVSID0gMTg5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfRE9VQkxFXzE5MF9GSUVMRF9OVU1CRVIgPSAxOTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVIgPSAxOTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEVudW0xOTEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9GSVhFRDMyXzE5Ml9GSUVMRF9OVU1CRVIgPSAxOTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9GSVhFRDY0XzE5M19GSUVMRF9OVU1CRVIgPSAxOTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfRkxPQVRfMTk0X0ZJRUxEX05VTUJFUiA9IDE5NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0RmxvYXQxOTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRGbG9hdDE5NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RmxvYXQxOTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGbG9hdDE5NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfSU5UMzJfMTk1X0ZJRUxEX05VTUJFUiA9IDE5NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0SW50MzIxOTVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50MzIxOTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50MzIxOTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfSU5UNjRfMTk2X0ZJRUxEX05VTUJFUiA9IDE5NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEludDY0MTk2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQ2NDE5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X01FU1NBR0VfMTk3X0ZJRUxEX05VTUJFUiA9IDE5NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDMyXzE5OF9GSUVMRF9OVU1CRVIgPSAxOTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDY0XzE5OV9GSUVMRF9OVU1CRVIgPSAxOTk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9TSU5UMzJfMjAwX0ZJRUxEX05VTUJFUiA9IDIwMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9TSU5UNjRfMjAxX0ZJRUxEX05VTUJFUiA9IDIwMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ludDY0MjAxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50NjQyMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU1RSSU5HXzIwMl9GSUVMRF9OVU1CRVIgPSAyMDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTdHJpbmcyMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9VSU5UMzJfMjAzX0ZJRUxEX05VTUJFUiA9IDIwMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9VSU5UNjRfMjA0X0ZJRUxEX05VTUJFUiA9IDIwNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLAogICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLAogICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLAogICAgICAgICAgRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLAogICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLAogICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGbG9hdDQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDU5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLAogICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLAogICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDY2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTAwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTU4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTY3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTczKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxODApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTg4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBmaWVsZE1hcEJvb2xCb29sMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXyA9IEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZmllbGRNYXBCb29sQnl0ZXMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfXyA9IEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGZpZWxkTWFwQm9vbERvdWJsZTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sRW51bTRfXyA9IEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBmaWVsZE1hcEJvb2xFbnVtNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fID0gRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18gPSBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgZmllbGRNYXBCb29sRml4ZWQ2NDZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3X18gPSBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGZpZWxkTWFwQm9vbEZsb2F0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sSW50MzI4X18gPSBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIGZpZWxkTWFwQm9vbEludDMyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18gPSBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGZpZWxkTWFwQm9vbEludDY0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fID0gRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZmllbGRNYXBCb29sTWVzc2FnZTEwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV9fID0gRmllbGRNYXBCb29sU2ZpeGVkMzIxMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEsIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyX18gPSBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMiwgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM19fID0gRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzLCBmaWVsZE1hcEJvb2xTaW50MzIxM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF9fID0gRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0LCBmaWVsZE1hcEJvb2xTaW50NjQxNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBCb29sU3RyaW5nMTVfXyA9IEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNSwgZmllbGRNYXBCb29sU3RyaW5nMTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sVWludDMyMTZfXyA9IEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgZmllbGRNYXBCb29sVWludDMyMTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfXyA9IEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNywgZmllbGRNYXBCb29sVWludDY0MTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fID0gRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOCwgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5X18gPSBGaWVsZE1hcEZpeGVkMzJCeXRlczE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOSwgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXyA9IEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMCwgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fID0gRmllbGRNYXBGaXhlZDMyRW51bTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMSwgZmllbGRNYXBGaXhlZDMyRW51bTIxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXyA9IEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjIsIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18gPSBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIzLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfXyA9IEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI0LCBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMySW50MzIyNV9fID0gRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjUsIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2X18gPSBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNiwgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN19fID0gRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNywgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fID0gRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjgsIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18gPSBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyOSwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fID0gRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMwLCBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fID0gRmllbGRNYXBGaXhlZDMyU2ludDY0MzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMxLCBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXyA9IEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzMiwgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXyA9IEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzMywgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXyA9IEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNCwgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fID0gRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNSwgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18gPSBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNiwgZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXyA9IEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNywgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF9fID0gRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzOCwgZmllbGRNYXBGaXhlZDY0RW51bTM4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXyA9IEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMzksIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwX18gPSBGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQwLCBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXyA9IEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQxLCBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fID0gRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDIsIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18gPSBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0MywgZmllbGRNYXBGaXhlZDY0SW50NjQ0M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fID0gRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NCwgZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fID0gRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDUsIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18gPSBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NiwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fID0gRmllbGRNYXBGaXhlZDY0U2ludDMyNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ3LCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fID0gRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ4LCBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyA9IEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MCwgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MSwgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEludDMyQm9vbDUyX18gPSBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MiwgZmllbGRNYXBJbnQzMkJvb2w1Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTMsIGZpZWxkTWFwSW50MzJCeXRlczUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18gPSBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU0LCBmaWVsZE1hcEludDMyRG91YmxlNTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyRW51bTU1X18gPSBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1NSwgZmllbGRNYXBJbnQzMkVudW01NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXyA9IEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU2LCBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fID0gRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTcsIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF9fID0gRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU4LCBmaWVsZE1hcEludDMyRmxvYXQ1OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fID0gRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU5LCBmaWVsZE1hcEludDMySW50MzI1OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF9fID0gRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYwLCBmaWVsZE1hcEludDMySW50NjQ2MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICBmaWVsZE1hcEludDMyTWVzc2FnZTYxX18gPSBGaWVsZE1hcEludDMyTWVzc2FnZTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MSwgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fID0gRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYyLCBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fID0gRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYzLCBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18gPSBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY0LCBmaWVsZE1hcEludDMyU2ludDMyNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fID0gRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NSwgZmllbGRNYXBJbnQzMlNpbnQ2NDY1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2X18gPSBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY2LCBmaWVsZE1hcEludDMyU3RyaW5nNjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N19fID0gRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NywgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfXyA9IEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjgsIGZpZWxkTWFwSW50MzJVaW50NjQ2OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfXyA9IEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY5LCBmaWVsZE1hcEludDY0Qm9vbDY5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXyA9IEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3MCwgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfXyA9IEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzEsIGZpZWxkTWFwSW50NjREb3VibGU3MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRFbnVtNzJfXyA9IEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcyLCBmaWVsZE1hcEludDY0RW51bTcyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M19fID0gRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzMsIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0X18gPSBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3NCwgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1X18gPSBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzUsIGZpZWxkTWFwSW50NjRGbG9hdDc1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2X18gPSBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzYsIGZpZWxkTWFwSW50NjRJbnQzMjc2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18gPSBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzcsIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXyA9IEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc4LCBmaWVsZE1hcEludDY0TWVzc2FnZTc4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18gPSBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzksIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18gPSBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODAsIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfXyA9IEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODEsIGZpZWxkTWFwSW50NjRTaW50MzI4MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18gPSBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgyLCBmaWVsZE1hcEludDY0U2ludDY0ODJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfXyA9IEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODMsIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQzMjg0X18gPSBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg0LCBmaWVsZE1hcEludDY0VWludDMyODRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fID0gRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4NSwgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fID0gRmllbGRNYXBTZml4ZWQzMkJvb2w4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODYsIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fID0gRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg3LCBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fID0gRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4OCwgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fID0gRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODksIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18gPSBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5MCwgZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXyA9IEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkxLCBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXyA9IEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5MiwgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXyA9IEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5MywgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXyA9IEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NCwgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fID0gRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTUsIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NiwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NywgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fID0gRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5OCwgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTksIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18gPSBGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDAsIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDEsIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDIsIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXyA9IEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDMsIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fID0gRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDQsIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDUsIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDYsIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18gPSBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTA3LCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fID0gRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOCwgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18gPSBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOSwgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyA9IEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEwLCBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fID0gRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTEsIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXyA9IEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTIsIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEzLCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fID0gRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTQsIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExNSwgZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExNiwgZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18gPSBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTcsIGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18gPSBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTgsIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18gPSBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTksIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fID0gRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjAsIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fID0gRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIxLCBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl9fID0gRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyMiwgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM19fID0gRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjMsIGZpZWxkTWFwU2ludDMyRW51bTEyM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18gPSBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNCwgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXyA9IEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTI1LCBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXyA9IEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNiwgZmllbGRNYXBTaW50MzJGbG9hdDEyNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXyA9IEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNywgZmllbGRNYXBTaW50MzJJbnQzMjEyN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXyA9IEZpZWxkTWFwU2ludDMySW50NjQxMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyOCwgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fID0gRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjksIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfXyA9IEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMCwgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfXyA9IEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMSwgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fID0gRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMiwgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyA9IEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzMsIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fID0gRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzNCwgZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfXyA9IEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzUsIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18gPSBGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM2LCBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTaW50NjRCb29sMTM3X18gPSBGaWVsZE1hcFNpbnQ2NEJvb2wxMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzNywgZmllbGRNYXBTaW50NjRCb29sMTM3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4X18gPSBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzgsIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18gPSBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM5LCBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRFbnVtMTQwX18gPSBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0MCwgZmllbGRNYXBTaW50NjRFbnVtMTQwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXyA9IEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQxLCBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fID0gRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDIsIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M19fID0gRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQzLCBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRJbnQzMjE0NF9fID0gRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ0LCBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRJbnQ2NDE0NV9fID0gRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ1LCBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18gPSBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0NiwgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fID0gRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ3LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fID0gRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ4LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5X18gPSBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ5LCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fID0gRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MCwgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18gPSBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUxLCBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MiwgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfXyA9IEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTMsIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18gPSBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NCwgZmllbGRNYXBTdHJpbmdCb29sMTU0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTU1LCBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfXyA9IEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTYsIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18gPSBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NywgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OCwgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OSwgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fID0gRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTYwLCBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXyA9IEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2MSwgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18gPSBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjIsIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18gPSBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2MywgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXyA9IEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2NCwgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18gPSBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjUsIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18gPSBGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY2LCBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXyA9IEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjcsIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfXyA9IEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjgsIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV9fID0gRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2OSwgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwX18gPSBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcwLCBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxX18gPSBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3MSwgZmllbGRNYXBVaW50MzJCb29sMTcxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18gPSBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzIsIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwVWludDMyRG91YmxlMTczX18gPSBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTczLCBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0X18gPSBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3NCwgZmllbGRNYXBVaW50MzJFbnVtMTc0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXyA9IEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc1LCBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fID0gRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzYsIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fID0gRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc3LCBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fID0gRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc4LCBmaWVsZE1hcFVpbnQzMkludDMyMTc4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fID0gRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc5LCBmaWVsZE1hcFVpbnQzMkludDY0MTc5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18gPSBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4MCwgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV9fID0gRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgxLCBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml9fID0gRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgyLCBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18gPSBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgzLCBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF9fID0gRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4NCwgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1X18gPSBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg1LCBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fID0gRmllbGRNYXBVaW50MzJVaW50MzIxODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4NiwgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyA9IEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODcsIGZpZWxkTWFwVWludDMyVWludDY0MTg3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXyA9IEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg4LCBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfXyA9IEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4OSwgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyA9IEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTAsIGZpZWxkTWFwVWludDY0RG91YmxlMTkwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXyA9IEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTkxLCBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fID0gRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTIsIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18gPSBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5MywgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0X18gPSBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTQsIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDMyMTk1X18gPSBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTUsIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDY0MTk2X18gPSBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTYsIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyA9IEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTk3LCBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTgsIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXyA9IEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDAsIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAxLCBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDIsIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzX18gPSBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAzLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fID0gRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNCwgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQk9PTF8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQllURVNfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRE9VQkxFXzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRU5VTV80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9GSVhFRDMyXzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZMT0FUXzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfSU5UMzJfOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NGSVhFRDMyXzExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0lOVDMyXzEzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9TSU5UNjRfMTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NUUklOR18xNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfVUlOVDMyXzE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9VSU5UNjRfMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9ET1VCTEVfMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9FTlVNXzIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVEMzJfMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRklYRUQ2NF8yM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRkxPQVRfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9JTlQzMl8yNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0lOVDY0XzI2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TRklYRUQzMl8yOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDY0XzI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NJTlQzMl8zMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfU0lOVDY0XzMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1VJTlQzMl8zM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfVUlOVDY0XzM0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQk9PTF8zNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQllURVNfMzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRE9VQkxFXzM3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZJWEVENjRfNDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZMT0FUXzQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9JTlQ2NF80M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfTUVTU0FHRV80NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU0ZJWEVEMzJfNDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQ2NF80Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UMzJfNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1NJTlQ2NF80OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU1RSSU5HXzQ5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UMzJfNTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1VJTlQ2NF81MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQk9PTF81Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQllURVNfNTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRE9VQkxFXzU0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRU5VTV81NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9GSVhFRDMyXzU2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZJWEVENjRfNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZMT0FUXzU4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfSU5UMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9JTlQ2NF82MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfTUVTU0FHRV82MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVEMzJfNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TRklYRUQ2NF82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1NJTlQ2NF82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU1RSSU5HXzY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9VSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1VJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JPT0xfNjlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JZVEVTXzcwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0RPVUJMRV83MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0VOVU1fNzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfRklYRUQzMl83M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GSVhFRDY0Xzc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0lOVDMyXzc2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfSU5UNjRfNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X01FU1NBR0VfNzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NGSVhFRDMyXzc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVENjRfODBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0lOVDMyXzgxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9TSU5UNjRfODJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfVUlOVDMyXzg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9VSU5UNjRfODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CT09MXzg2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CWVRFU184N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9ET1VCTEVfODhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0ZJWEVEMzJfOTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRkxPQVRfOTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9JTlQzMl85M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9NRVNTQUdFXzk1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQzMl85Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NGSVhFRDY0Xzk3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NJTlQzMl85OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDY0Xzk5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU1RSSU5HXzEwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9VSU5UMzJfMTAxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1VJTlQ2NF8xMDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JPT0xfMTAzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JZVEVTXzEwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0RPVUJMRV8xMDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0VOVU1fMTA2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfRklYRUQzMl8xMDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GTE9BVF8xMDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0lOVDMyXzExMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X01FU1NBR0VfMTEyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDMyXzExM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0ZJWEVENjRfMTE0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0lOVDMyXzExNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UNjRfMTE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NUUklOR18xMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfVUlOVDMyXzExOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UNjRfMTE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0RPVUJMRV8xMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0VOVU1fMTIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfRklYRUQzMl8xMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GSVhFRDY0XzEyNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GTE9BVF8xMjZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0lOVDMyXzEyN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfSU5UNjRfMTI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NGSVhFRDMyXzEzMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVENjRfMTMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0lOVDMyXzEzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9TSU5UNjRfMTMzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfVUlOVDMyXzEzNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9VSU5UNjRfMTM2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CT09MXzEzN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CWVRFU18xMzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9ET1VCTEVfMTM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRklYRUQ2NF8xNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRkxPQVRfMTQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0lOVDY0XzE0NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9NRVNTQUdFXzE0Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TRklYRUQzMl8xNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDY0XzE0OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NJTlQzMl8xNDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfU0lOVDY0XzE1MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TVFJJTkdfMTUxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1VJTlQzMl8xNTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfVUlOVDY0XzE1M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQk9PTF8xNTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQllURVNfMTU1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRE9VQkxFXzE1Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRU5VTV8xNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19GSVhFRDMyXzE1OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZJWEVENjRfMTU5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZMT0FUXzE2MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfSU5UMzJfMTYxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19JTlQ2NF8xNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfTUVTU0FHRV8xNjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVEMzJfMTY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TSU5UMzJfMTY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1NJTlQ2NF8xNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU1RSSU5HXzE2OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19VSU5UMzJfMTY5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1VJTlQ2NF8xNzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0RPVUJMRV8xNzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0VOVU1fMTc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfRklYRUQzMl8xNzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GSVhFRDY0XzE3Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GTE9BVF8xNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0lOVDMyXzE3OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfSU5UNjRfMTc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NGSVhFRDMyXzE4MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVENjRfMTgyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0lOVDMyXzE4M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9TSU5UNjRfMTg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfVUlOVDMyXzE4Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9VSU5UNjRfMTg3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CT09MXzE4OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CWVRFU18xODlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9ET1VCTEVfMTkwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRklYRUQ2NF8xOTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRkxPQVRfMTk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0lOVDY0XzE5Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9NRVNTQUdFXzE5N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TRklYRUQzMl8xOThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDY0XzE5OV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NJTlQzMl8yMDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfU0lOVDY0XzIwMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TVFJJTkdfMjAyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1VJTlQzMl8yMDNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfVUlOVDY0XzIwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKTsKICAgICAgICAgIGNhc2UgMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICAgIGNhc2UgMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKTsKICAgICAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgICBjYXNlIDE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKTsKICAgICAgICAgIGNhc2UgMTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgICAgY2FzZSAxODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCk7CiAgICAgICAgICBjYXNlIDE5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAgICAgICBjYXNlIDIwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgICAgY2FzZSAyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCk7CiAgICAgICAgICBjYXNlIDIyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICAgIGNhc2UgMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpOwogICAgICAgICAgY2FzZSAyNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgICAgY2FzZSAyNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgICAgY2FzZSAyNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCk7CiAgICAgICAgICBjYXNlIDI4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCk7CiAgICAgICAgICBjYXNlIDI5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgICBjYXNlIDMwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpOwogICAgICAgICAgY2FzZSAzMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgICBjYXNlIDMzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpOwogICAgICAgICAgY2FzZSAzNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIGNhc2UgMzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgY2FzZSAzNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpOwogICAgICAgICAgY2FzZSAzNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIGNhc2UgMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgY2FzZSAzOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCk7CiAgICAgICAgICBjYXNlIDQwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgICAgICAgIGNhc2UgNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICAgIGNhc2UgNDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKTsKICAgICAgICAgIGNhc2UgNDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKTsKICAgICAgICAgIGNhc2UgNDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgICAgY2FzZSA0NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpOwogICAgICAgICAgY2FzZSA0NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgICAgICAgY2FzZSA0NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIGNhc2UgNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCk7CiAgICAgICAgICBjYXNlIDQ5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpOwogICAgICAgICAgY2FzZSA1MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIGNhc2UgNTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCk7CiAgICAgICAgICBjYXNlIDUyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICBjYXNlIDUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgICAgY2FzZSA1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCk7CiAgICAgICAgICBjYXNlIDU1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICBjYXNlIDU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICBjYXNlIDU3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAgICAgICBjYXNlIDU4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgICAgICAgY2FzZSA1OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIGNhc2UgNjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCk7CiAgICAgICAgICBjYXNlIDYxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAgICAgICBjYXNlIDYyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgICAgY2FzZSA2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgICAgICAgIGNhc2UgNjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgY2FzZSA2NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICBjYXNlIDY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKTsKICAgICAgICAgIGNhc2UgNjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgICAgICAgY2FzZSA2ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICBjYXNlIDY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCk7CiAgICAgICAgICBjYXNlIDcwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgY2FzZSA3MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICBjYXNlIDcyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCk7CiAgICAgICAgICBjYXNlIDczOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCk7CiAgICAgICAgICBjYXNlIDc0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgICBjYXNlIDc1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgICAgICAgY2FzZSA3NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKTsKICAgICAgICAgIGNhc2UgNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgICBjYXNlIDc4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCk7CiAgICAgICAgICBjYXNlIDc5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgY2FzZSA4MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICAgIGNhc2UgODE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpOwogICAgICAgICAgY2FzZSA4MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICBjYXNlIDgzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICAgIGNhc2UgODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpOwogICAgICAgICAgY2FzZSA4NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICBjYXNlIDg2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgICBjYXNlIDg3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpOwogICAgICAgICAgY2FzZSA4ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICBjYXNlIDg5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgICBjYXNlIDkwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCk7CiAgICAgICAgICBjYXNlIDkxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAgICAgICBjYXNlIDkyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgY2FzZSA5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKTsKICAgICAgICAgIGNhc2UgOTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCk7CiAgICAgICAgICBjYXNlIDk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgICBjYXNlIDk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpOwogICAgICAgICAgY2FzZSA5NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgICAgICAgIGNhc2UgOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgICAgY2FzZSA5OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCk7CiAgICAgICAgICBjYXNlIDEwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgICAgY2FzZSAxMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCk7CiAgICAgICAgICBjYXNlIDEwMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgICAgICAgIGNhc2UgMTA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICAgIGNhc2UgMTA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCk7CiAgICAgICAgICBjYXNlIDEwNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgICAgICAgIGNhc2UgMTA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgICAgY2FzZSAxMDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCk7CiAgICAgICAgICBjYXNlIDEwOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAgICAgICBjYXNlIDExMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgICBjYXNlIDExMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCk7CiAgICAgICAgICBjYXNlIDExMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKTsKICAgICAgICAgIGNhc2UgMTE1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAgICAgICBjYXNlIDExNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgICAgY2FzZSAxMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKTsKICAgICAgICAgIGNhc2UgMTE4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAgICAgICBjYXNlIDExOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgICAgY2FzZSAxMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpOwogICAgICAgICAgY2FzZSAxMjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgICAgICAgIGNhc2UgMTIyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgICAgY2FzZSAxMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpOwogICAgICAgICAgY2FzZSAxMjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgICAgICAgY2FzZSAxMjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgICAgY2FzZSAxMjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKTsKICAgICAgICAgIGNhc2UgMTI3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAgICAgICBjYXNlIDEyODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgICAgY2FzZSAxMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpOwogICAgICAgICAgY2FzZSAxMzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKTsKICAgICAgICAgIGNhc2UgMTMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICBjYXNlIDEzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKTsKICAgICAgICAgIGNhc2UgMTMzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpOwogICAgICAgICAgY2FzZSAxMzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgICBjYXNlIDEzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKTsKICAgICAgICAgIGNhc2UgMTM2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpOwogICAgICAgICAgY2FzZSAxMzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgY2FzZSAxMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKTsKICAgICAgICAgIGNhc2UgMTM5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpOwogICAgICAgICAgY2FzZSAxNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgY2FzZSAxNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpOwogICAgICAgICAgY2FzZSAxNDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgY2FzZSAxNDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICAgIGNhc2UgMTQ0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCk7CiAgICAgICAgICBjYXNlIDE0NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgICAgICAgY2FzZSAxNDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgICAgY2FzZSAxNDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKTsKICAgICAgICAgIGNhc2UgMTQ4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICBjYXNlIDE0OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIGNhc2UgMTUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpOwogICAgICAgICAgY2FzZSAxNTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAgICAgICBjYXNlIDE1MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIGNhc2UgMTUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpOwogICAgICAgICAgY2FzZSAxNTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgY2FzZSAxNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICAgIGNhc2UgMTU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpOwogICAgICAgICAgY2FzZSAxNTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgY2FzZSAxNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgY2FzZSAxNTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgICAgICAgY2FzZSAxNjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKTsKICAgICAgICAgIGNhc2UgMTYxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgICBjYXNlIDE2MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpOwogICAgICAgICAgY2FzZSAxNjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpOwogICAgICAgICAgY2FzZSAxNjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIGNhc2UgMTY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCk7CiAgICAgICAgICBjYXNlIDE2NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgICAgICAgIGNhc2UgMTY3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgY2FzZSAxNjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCk7CiAgICAgICAgICBjYXNlIDE2OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKTsKICAgICAgICAgIGNhc2UgMTcwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgY2FzZSAxNzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpOwogICAgICAgICAgY2FzZSAxNzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIGNhc2UgMTczOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgY2FzZSAxNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpOwogICAgICAgICAgY2FzZSAxNzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpOwogICAgICAgICAgY2FzZSAxNzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgICAgY2FzZSAxNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKTsKICAgICAgICAgIGNhc2UgMTc4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCk7CiAgICAgICAgICBjYXNlIDE3OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgICAgY2FzZSAxODA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpOwogICAgICAgICAgY2FzZSAxODE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIGNhc2UgMTgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgICBjYXNlIDE4MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKTsKICAgICAgICAgIGNhc2UgMTg0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgY2FzZSAxODU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgICBjYXNlIDE4NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKTsKICAgICAgICAgIGNhc2UgMTg3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgY2FzZSAxODg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgICAgY2FzZSAxODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgICAgICAgIGNhc2UgMTkwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgY2FzZSAxOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgICAgY2FzZSAxOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpOwogICAgICAgICAgY2FzZSAxOTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgICAgICAgY2FzZSAxOTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICAgIGNhc2UgMTk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCk7CiAgICAgICAgICBjYXNlIDE5NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgICAgY2FzZSAxOTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgICAgY2FzZSAxOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKTsKICAgICAgICAgIGNhc2UgMTk5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAgICAgICBjYXNlIDIwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpOwogICAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgICBjYXNlIDIwMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKTsKICAgICAgICAgIGNhc2UgMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCk7CiAgICAgICAgICBjYXNlIDEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgICBjYXNlIDE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKTsKICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKTsKICAgICAgICAgIGNhc2UgMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICAgIGNhc2UgMTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAgICAgICBjYXNlIDIwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKTsKICAgICAgICAgIGNhc2UgMjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICAgIGNhc2UgMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICAgIGNhc2UgMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgICBjYXNlIDI1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgICAgY2FzZSAyNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKTsKICAgICAgICAgIGNhc2UgMjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICAgIGNhc2UgMjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCk7CiAgICAgICAgICBjYXNlIDI5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpOwogICAgICAgICAgY2FzZSAzMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgICBjYXNlIDMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpOwogICAgICAgICAgY2FzZSAzMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgICBjYXNlIDM0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIGNhc2UgMzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKTsKICAgICAgICAgIGNhc2UgMzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICBjYXNlIDM3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIGNhc2UgMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKTsKICAgICAgICAgIGNhc2UgMzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICAgIGNhc2UgNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgICAgICAgIGNhc2UgNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAgICAgICBjYXNlIDQyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgICAgY2FzZSA0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKTsKICAgICAgICAgIGNhc2UgNDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKTsKICAgICAgICAgIGNhc2UgNDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICBjYXNlIDQ2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgICAgICAgY2FzZSA0NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCk7CiAgICAgICAgICBjYXNlIDQ4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIGNhc2UgNDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpOwogICAgICAgICAgY2FzZSA1MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCk7CiAgICAgICAgICBjYXNlIDUxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIGNhc2UgNTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICBjYXNlIDUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICAgIGNhc2UgNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICBjYXNlIDU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpOwogICAgICAgICAgY2FzZSA1NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICAgIGNhc2UgNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgICAgICAgY2FzZSA1OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCk7CiAgICAgICAgICBjYXNlIDYwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIGNhc2UgNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAgICAgICBjYXNlIDYyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKTsKICAgICAgICAgIGNhc2UgNjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgICAgY2FzZSA2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgY2FzZSA2NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpOwogICAgICAgICAgY2FzZSA2NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgICAgY2FzZSA2NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgICAgICAgY2FzZSA2ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpOwogICAgICAgICAgY2FzZSA2OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIGNhc2UgNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgY2FzZSA3MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpOwogICAgICAgICAgY2FzZSA3MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIGNhc2UgNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCk7CiAgICAgICAgICBjYXNlIDc0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpOwogICAgICAgICAgY2FzZSA3NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgICBjYXNlIDc2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKTsKICAgICAgICAgIGNhc2UgNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpOwogICAgICAgICAgY2FzZSA3ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICAgIGNhc2UgNzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgY2FzZSA4MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCk7CiAgICAgICAgICBjYXNlIDgxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICBjYXNlIDgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICBjYXNlIDgzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCk7CiAgICAgICAgICBjYXNlIDg0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICBjYXNlIDg1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICBjYXNlIDg2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpOwogICAgICAgICAgY2FzZSA4NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgICBjYXNlIDg4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICBjYXNlIDg5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpOwogICAgICAgICAgY2FzZSA5MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIGNhc2UgOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAgICAgICBjYXNlIDkyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKTsKICAgICAgICAgIGNhc2UgOTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgY2FzZSA5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCk7CiAgICAgICAgICBjYXNlIDk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpOwogICAgICAgICAgY2FzZSA5NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgICBjYXNlIDk3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgICAgICAgIGNhc2UgOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKTsKICAgICAgICAgIGNhc2UgOTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICAgIGNhc2UgMTAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgICAgY2FzZSAxMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCk7CiAgICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICAgIGNhc2UgMTAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgICAgICAgIGNhc2UgMTA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCk7CiAgICAgICAgICBjYXNlIDEwNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICAgIGNhc2UgMTA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgICAgICAgIGNhc2UgMTA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKTsKICAgICAgICAgIGNhc2UgMTA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICAgIGNhc2UgMTA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAgICAgICBjYXNlIDExMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpOwogICAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCk7CiAgICAgICAgICBjYXNlIDExNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgICAgY2FzZSAxMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAgICAgICBjYXNlIDExNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKTsKICAgICAgICAgIGNhc2UgMTE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgICAgY2FzZSAxMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAgICAgICBjYXNlIDExOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKTsKICAgICAgICAgIGNhc2UgMTIwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgICBjYXNlIDEyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgICAgICAgIGNhc2UgMTIyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKTsKICAgICAgICAgIGNhc2UgMTIzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgICBjYXNlIDEyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgICAgICAgY2FzZSAxMjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKTsKICAgICAgICAgIGNhc2UgMTI2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgICAgY2FzZSAxMjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAgICAgICBjYXNlIDEyODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKTsKICAgICAgICAgIGNhc2UgMTI5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgICBjYXNlIDEzMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKTsKICAgICAgICAgIGNhc2UgMTMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpOwogICAgICAgICAgY2FzZSAxMzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgICAgY2FzZSAxMzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpOwogICAgICAgICAgY2FzZSAxMzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpOwogICAgICAgICAgY2FzZSAxMzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgICAgY2FzZSAxMzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpOwogICAgICAgICAgY2FzZSAxMzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKTsKICAgICAgICAgIGNhc2UgMTM4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgICAgY2FzZSAxMzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpOwogICAgICAgICAgY2FzZSAxNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKTsKICAgICAgICAgIGNhc2UgMTQxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgICBjYXNlIDE0MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgY2FzZSAxNDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCk7CiAgICAgICAgICBjYXNlIDE0NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICAgIGNhc2UgMTQ1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgICAgICAgY2FzZSAxNDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKTsKICAgICAgICAgIGNhc2UgMTQ3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgICAgY2FzZSAxNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICBjYXNlIDE0OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCk7CiAgICAgICAgICBjYXNlIDE1MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgICBjYXNlIDE1MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAgICAgICBjYXNlIDE1MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCk7CiAgICAgICAgICBjYXNlIDE1MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgICBjYXNlIDE1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgY2FzZSAxNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCk7CiAgICAgICAgICBjYXNlIDE1NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgICBjYXNlIDE1NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgY2FzZSAxNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKTsKICAgICAgICAgIGNhc2UgMTU5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgICBjYXNlIDE2MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKTsKICAgICAgICAgIGNhc2UgMTYxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpOwogICAgICAgICAgY2FzZSAxNjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgICBjYXNlIDE2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpOwogICAgICAgICAgY2FzZSAxNjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCk7CiAgICAgICAgICBjYXNlIDE2NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIGNhc2UgMTY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgICAgICAgIGNhc2UgMTY3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKTsKICAgICAgICAgIGNhc2UgMTY4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICAgIGNhc2UgMTY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKTsKICAgICAgICAgIGNhc2UgMTcwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKTsKICAgICAgICAgIGNhc2UgMTcxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICBjYXNlIDE3MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIGNhc2UgMTczOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKTsKICAgICAgICAgIGNhc2UgMTc0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICBjYXNlIDE3NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpOwogICAgICAgICAgY2FzZSAxNzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKTsKICAgICAgICAgIGNhc2UgMTc3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgICAgY2FzZSAxNzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCk7CiAgICAgICAgICBjYXNlIDE3OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgICAgICAgIGNhc2UgMTgwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgICBjYXNlIDE4MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIGNhc2UgMTgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpOwogICAgICAgICAgY2FzZSAxODM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgY2FzZSAxODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgY2FzZSAxODU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgICAgICAgY2FzZSAxODY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgY2FzZSAxODc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgY2FzZSAxODg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKTsKICAgICAgICAgIGNhc2UgMTg5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgICAgY2FzZSAxOTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgY2FzZSAxOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKTsKICAgICAgICAgIGNhc2UgMTkyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICBjYXNlIDE5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgICAgICAgY2FzZSAxOTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCk7CiAgICAgICAgICBjYXNlIDE5NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICAgIGNhc2UgMTk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgICAgY2FzZSAxOTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKTsKICAgICAgICAgIGNhc2UgMTk4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgICAgY2FzZSAxOTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAgICAgICBjYXNlIDIwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCk7CiAgICAgICAgICBjYXNlIDIwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgICBjYXNlIDIwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgICBjYXNlIDIwMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCk7CiAgICAgICAgICBjYXNlIDIwNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgYml0RmllbGQyXyA9IDA7CiAgICAgICAgYml0RmllbGQzXyA9IDA7CiAgICAgICAgYml0RmllbGQ0XyA9IDA7CiAgICAgICAgYml0RmllbGQ1XyA9IDA7CiAgICAgICAgYml0RmllbGQ2XyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMShyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMl8gIT0gMCkgeyBidWlsZFBhcnRpYWwyKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQzXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDMocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDRfICE9IDApIHsgYnVpbGRQYXJ0aWFsNChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkNV8gIT0gMCkgeyBidWlsZFBhcnRpYWw1KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQ2XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDYocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCb29sMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sQm9vbDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCeXRlczJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCeXRlczJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xEb3VibGUzXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbERvdWJsZTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xFbnVtNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRW51bTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGaXhlZDMyNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRml4ZWQzMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGaXhlZDY0Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRml4ZWQ2NDZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGbG9hdDdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGbG9hdDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQzMjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQzMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQ2NDlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQ2NDlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xNZXNzYWdlMTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5idWlsZChGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTZml4ZWQzMjExXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTZml4ZWQ2NDEyXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTaW50MzIxM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ludDMyMTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTaW50NjQxNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ludDY0MTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTdHJpbmcxNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU3RyaW5nMTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xVaW50MzIxNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sVWludDMyMTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xVaW50NjQxN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sVWludDY0MTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCb29sMThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCb29sMThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJEb3VibGUyMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJFbnVtMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkludDMyMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkludDY0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5idWlsZChGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50MzIzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50NjQzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjREb3VibGUzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEVudW0zOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDMyNDJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0SW50MzI0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDY0NDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0SW50NjQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmJ1aWxkKEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50MzI0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50MzI1MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCb29sNTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkJvb2w1Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCeXRlczUzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyQnl0ZXM1M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJEb3VibGU1NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJFbnVtNTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkVudW01NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGbG9hdDU4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRmxvYXQ1OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJJbnQzMjU5XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50MzI1OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50NjQ2MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuYnVpbGQoRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkNjQ2M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTaW50MzI2NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTaW50MzI2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMl8gPSBiaXRGaWVsZDJfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNpbnQ2NDY1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlN0cmluZzY2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQzMjY3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQ2NDY4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJvb2w2OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Qm9vbDY5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRCeXRlczcwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NERvdWJsZTcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEVudW03Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RW51bTcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQzMjczXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQ2NDc0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRGbG9hdDc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDMyNzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRJbnQzMjc2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDY0NzdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRJbnQ2NDc3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5idWlsZChGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQzMjgxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFN0cmluZzgzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQzMjg0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQ2NDg1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRW51bTg5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5idWlsZChGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQzXyA9IGJpdEZpZWxkM187CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDMyOThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuYnVpbGQoRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0VWludDMyMTE4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJvb2wxMjBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJvb2wxMjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJEb3VibGUxMjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkVudW0xMjNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkVudW0xMjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRmxvYXQxMjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkludDMyMTI3XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMySW50MzIxMjdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkludDY0MTI4XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMySW50NjQxMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWw0KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDRfID0gYml0RmllbGQ0XzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmJ1aWxkKEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlN0cmluZzEzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qm9vbDEzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRCeXRlczEzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RW51bTE0MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RW51bTE0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RmxvYXQxNDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRGbG9hdDE0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRJbnQzMjE0NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmJ1aWxkKEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQm9vbDE1NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdCeXRlczE1NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRW51bTE1N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRW51bTE1N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDUoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNV8gPSBiaXRGaWVsZDVfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDMyMTYxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDY0MTYyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuYnVpbGQoRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCb29sMTcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkJ5dGVzMTcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyRG91YmxlMTczXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJFbnVtMTc0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZsb2F0MTc3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDMyMTc4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDY0MTc5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuYnVpbGQoRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50MzIxODNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ludDMyMTgzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50NjQxODRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ludDY0MTg0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU3RyaW5nMTg1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50MzIxODZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyVWludDMyMTg2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50NjQxODdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyVWludDY0MTg3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCb29sMTg4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjREb3VibGUxOTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0RG91YmxlMTkwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRFbnVtMTkxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsNihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQ2XyA9IGJpdEZpZWxkNl87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0RmxvYXQxOTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEludDMyMTk1XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0SW50MzIxOTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEludDY0MTk2XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0SW50NjQxOTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5idWlsZChGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTaW50MzIyMDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTaW50NjQyMDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRVaW50MzIyMDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRVaW50NjQyMDRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoTWFwcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKS52YWx1ZXMoKSkgewogICAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKS52YWx1ZXMoKSkgewogICAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKS52YWx1ZXMoKSkgewogICAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBpdGVtIDogZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgaXRlbSA6IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGl0ZW0gOiBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKS52YWx1ZXMoKSkgewogICAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCb29sMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEJvb2wxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEJ5dGVzMl9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xCeXRlczJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xEb3VibGUzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sRG91YmxlM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEVudW00X18gPSBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBCb29sRW51bTRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDQsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEVudW00X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEVudW00X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQzMjVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkMzI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDY0Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGbG9hdDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N19fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xGbG9hdDdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sSW50MzI4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQzMjhfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sSW50MzI4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEludDY0OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEludDY0OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sTWVzc2FnZTEwX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTZml4ZWQzMjExX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwCiAgICAgICAgICAgICAgY2FzZSA5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ludDMyMTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM19fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTaW50MzIxM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNgogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ludDY0MTRfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sU2ludDY0MTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU3RyaW5nMTVfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sU3RyaW5nMTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgICBjYXNlIDEzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50MzIxNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMwCiAgICAgICAgICAgICAgY2FzZSAxMzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50NjQxN19fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xVaW50NjQxN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzOAogICAgICAgICAgICAgIGNhc2UgMTQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NgogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCeXRlczE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NAogICAgICAgICAgICAgIGNhc2UgMTYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRW51bTIxX18gPSBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRW51bTIxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzAKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzgKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODYKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQzMjI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMySW50MzIyNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMgogICAgICAgICAgICAgIGNhc2UgMjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIyNgogICAgICAgICAgICAgIGNhc2UgMjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjM0CiAgICAgICAgICAgICAgY2FzZSAyNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MgogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBjYXNlIDI2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY2CiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3NAogICAgICAgICAgICAgIGNhc2UgMjgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MgogICAgICAgICAgICAgIGNhc2UgMjkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4X18gPSBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkTWFwRml4ZWQ2NEVudW0zOF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMzgsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0RW51bTM4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDYKICAgICAgICAgICAgICBjYXNlIDMxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMTQKICAgICAgICAgICAgICBjYXNlIDMyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjIKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzAKICAgICAgICAgICAgICBjYXNlIDMzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50NjQ0M19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ2CiAgICAgICAgICAgICAgY2FzZSAzNTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTQKICAgICAgICAgICAgICBjYXNlIDM2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2MgogICAgICAgICAgICAgIGNhc2UgMzcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzcwCiAgICAgICAgICAgICAgY2FzZSAzNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3OAogICAgICAgICAgICAgIGNhc2UgMzg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzODYKICAgICAgICAgICAgICBjYXNlIDM5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzOTQKICAgICAgICAgICAgICBjYXNlIDQwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxMAogICAgICAgICAgICAgIGNhc2UgNDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCb29sNTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyQm9vbDUyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE4CiAgICAgICAgICAgICAgY2FzZSA0MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkJ5dGVzNTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MjYKICAgICAgICAgICAgICBjYXNlIDQzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkRvdWJsZTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQzNAogICAgICAgICAgICAgIGNhc2UgNDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkVudW01NV9fID0gRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBJbnQzMkVudW01NV9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoNTUsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkVudW01NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRW51bTU1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NDIKICAgICAgICAgICAgICBjYXNlIDQ1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQzMjU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1MAogICAgICAgICAgICAgIGNhc2UgNDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRml4ZWQ2NDU3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDU4CiAgICAgICAgICAgICAgY2FzZSA0NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGbG9hdDU4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkZsb2F0NThfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkZsb2F0NThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NjYKICAgICAgICAgICAgICBjYXNlIDQ3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQzMjU5X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJJbnQzMjU5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDc0CiAgICAgICAgICAgICAgY2FzZSA0ODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkludDY0NjBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF9fLmdldEtleSgpLCBmaWVsZE1hcEludDMySW50NjQ2MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4MgogICAgICAgICAgICAgIGNhc2UgNDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyTWVzc2FnZTYxX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OTAKICAgICAgICAgICAgICBjYXNlIDQ5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDk4CiAgICAgICAgICAgICAgY2FzZSA1MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fLmdldEtleSgpLCBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNgogICAgICAgICAgICAgIGNhc2UgNTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxNAogICAgICAgICAgICAgIGNhc2UgNTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQ2NDY1X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyMgogICAgICAgICAgICAgIGNhc2UgNTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU3RyaW5nNjZfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlN0cmluZzY2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTMwCiAgICAgICAgICAgICAgY2FzZSA1Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTM4CiAgICAgICAgICAgICAgY2FzZSA1NDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTQ2CiAgICAgICAgICAgICAgY2FzZSA1NTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEJvb2w2OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRCb29sNjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NTQKICAgICAgICAgICAgICBjYXNlIDU2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Qnl0ZXM3MF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0Qnl0ZXM3MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU2MgogICAgICAgICAgICAgIGNhc2UgNTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTcwCiAgICAgICAgICAgICAgY2FzZSA1Nzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyX18gPSBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcEludDY0RW51bTcyX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg3MiwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRFbnVtNzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU3OAogICAgICAgICAgICAgIGNhc2UgNTg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M19fLmdldEtleSgpLCBmaWVsZE1hcEludDY0Rml4ZWQzMjczX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTg2CiAgICAgICAgICAgICAgY2FzZSA1OTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OTQKICAgICAgICAgICAgICBjYXNlIDYwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RmxvYXQ3NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0RmxvYXQ3NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYwMgogICAgICAgICAgICAgIGNhc2UgNjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEludDMyNzZfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEludDMyNzZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MTAKICAgICAgICAgICAgICBjYXNlIDYxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjE4CiAgICAgICAgICAgICAgY2FzZSA2MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0TWVzc2FnZTc4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYyNgogICAgICAgICAgICAgIGNhc2UgNjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MzQKICAgICAgICAgICAgICBjYXNlIDY0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQyCiAgICAgICAgICAgICAgY2FzZSA2NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUwCiAgICAgICAgICAgICAgY2FzZSA2NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjU4CiAgICAgICAgICAgICAgY2FzZSA2NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fLmdldEtleSgpLCBmaWVsZE1hcEludDY0U3RyaW5nODNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NjYKICAgICAgICAgICAgICBjYXNlIDY3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0VWludDMyODRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NzQKICAgICAgICAgICAgICBjYXNlIDY4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0VWludDY0ODVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0VWludDY0ODVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODIKICAgICAgICAgICAgICBjYXNlIDY5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY5MAogICAgICAgICAgICAgIGNhc2UgNjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjk4CiAgICAgICAgICAgICAgY2FzZSA3MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MDYKICAgICAgICAgICAgICBjYXNlIDcxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXyA9IEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDg5LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzE0CiAgICAgICAgICAgICAgY2FzZSA3MjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjIKICAgICAgICAgICAgICBjYXNlIDczMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczMAogICAgICAgICAgICAgIGNhc2UgNzM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM4CiAgICAgICAgICAgICAgY2FzZSA3NDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NgogICAgICAgICAgICAgIGNhc2UgNzU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NTQKICAgICAgICAgICAgICBjYXNlIDc2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYyCiAgICAgICAgICAgICAgY2FzZSA3NzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MAogICAgICAgICAgICAgIGNhc2UgNzc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODYKICAgICAgICAgICAgICBjYXNlIDc5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTQKICAgICAgICAgICAgICBjYXNlIDgwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAyCiAgICAgICAgICAgICAgY2FzZSA4MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTAKICAgICAgICAgICAgICBjYXNlIDgxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgODI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBjYXNlIDgzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODM0CiAgICAgICAgICAgICAgY2FzZSA4NDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg0MgogICAgICAgICAgICAgIGNhc2UgODUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMTA2LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODUwCiAgICAgICAgICAgICAgY2FzZSA4NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg1OAogICAgICAgICAgICAgIGNhc2UgODY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NjYKICAgICAgICAgICAgICBjYXNlIDg3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODc0CiAgICAgICAgICAgICAgY2FzZSA4ODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODgyCiAgICAgICAgICAgICAgY2FzZSA4OTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDY0MTExX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEludDY0MTExX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODkwCiAgICAgICAgICAgICAgY2FzZSA4OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODk4CiAgICAgICAgICAgICAgY2FzZSA5MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTA2CiAgICAgICAgICAgICAgY2FzZSA5MTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTE0CiAgICAgICAgICAgICAgY2FzZSA5MjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MjIKICAgICAgICAgICAgICBjYXNlIDkzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzMAogICAgICAgICAgICAgIGNhc2UgOTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MzgKICAgICAgICAgICAgICBjYXNlIDk0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk0NgogICAgICAgICAgICAgIGNhc2UgOTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTU0CiAgICAgICAgICAgICAgY2FzZSA5NjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJCb29sMTIwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJvb2wxMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJCb29sMTIwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTYyCiAgICAgICAgICAgICAgY2FzZSA5NzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTcwCiAgICAgICAgICAgICAgY2FzZSA5Nzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTc4CiAgICAgICAgICAgICAgY2FzZSA5ODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXyA9IEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBTaW50MzJFbnVtMTIzX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxMjMsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJFbnVtMTIzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5ODYKICAgICAgICAgICAgICBjYXNlIDk5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OTQKICAgICAgICAgICAgICBjYXNlIDEwMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAwMgogICAgICAgICAgICAgIGNhc2UgMTAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGbG9hdDEyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDEwCiAgICAgICAgICAgICAgY2FzZSAxMDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkludDMyMTI3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAxOAogICAgICAgICAgICAgIGNhc2UgMTAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwMjYKICAgICAgICAgICAgICBjYXNlIDEwMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDM0CiAgICAgICAgICAgICAgY2FzZSAxMDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0MgogICAgICAgICAgICAgIGNhc2UgMTA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNTAKICAgICAgICAgICAgICBjYXNlIDEwNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNTgKICAgICAgICAgICAgICBjYXNlIDEwNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNjYKICAgICAgICAgICAgICBjYXNlIDEwNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA3NAogICAgICAgICAgICAgIGNhc2UgMTA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA4MgogICAgICAgICAgICAgIGNhc2UgMTA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA5MAogICAgICAgICAgICAgIGNhc2UgMTA5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDk4CiAgICAgICAgICAgICAgY2FzZSAxMTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRCeXRlczEzOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMDYKICAgICAgICAgICAgICBjYXNlIDExMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTExNAogICAgICAgICAgICAgIGNhc2UgMTEyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RW51bTE0MF9fID0gRmllbGRNYXBTaW50NjRFbnVtMTQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDE0MCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RW51bTE0MF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMjIKICAgICAgICAgICAgICBjYXNlIDExMzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEzMAogICAgICAgICAgICAgIGNhc2UgMTEzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTM4CiAgICAgICAgICAgICAgY2FzZSAxMTQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRGbG9hdDE0M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNDYKICAgICAgICAgICAgICBjYXNlIDExNTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRJbnQzMjE0NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTU0CiAgICAgICAgICAgICAgY2FzZSAxMTYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRJbnQ2NDE0NV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE2MgogICAgICAgICAgICAgIGNhc2UgMTE3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNzAKICAgICAgICAgICAgICBjYXNlIDExNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTc4CiAgICAgICAgICAgICAgY2FzZSAxMTg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE4NgogICAgICAgICAgICAgIGNhc2UgMTE5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50MzIxNDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE5NAogICAgICAgICAgICAgIGNhc2UgMTIwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIwMgogICAgICAgICAgICAgIGNhc2UgMTIxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjEwCiAgICAgICAgICAgICAgY2FzZSAxMjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjE4CiAgICAgICAgICAgICAgY2FzZSAxMjI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjI2CiAgICAgICAgICAgICAgY2FzZSAxMjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdCb29sMTU0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIzNAogICAgICAgICAgICAgIGNhc2UgMTI0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyNDIKICAgICAgICAgICAgICBjYXNlIDEyNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjUwCiAgICAgICAgICAgICAgY2FzZSAxMjU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfXyA9IEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBTdHJpbmdFbnVtMTU3X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxNTcsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjU4CiAgICAgICAgICAgICAgY2FzZSAxMjY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI2NgogICAgICAgICAgICAgIGNhc2UgMTI3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyNzQKICAgICAgICAgICAgICBjYXNlIDEyODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjgyCiAgICAgICAgICAgICAgY2FzZSAxMjkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjkwCiAgICAgICAgICAgICAgY2FzZSAxMjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjk4CiAgICAgICAgICAgICAgY2FzZSAxMzA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzA2CiAgICAgICAgICAgICAgY2FzZSAxMzE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzE0CiAgICAgICAgICAgICAgY2FzZSAxMzIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzIyCiAgICAgICAgICAgICAgY2FzZSAxMzMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMzAKICAgICAgICAgICAgICBjYXNlIDEzMzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMzOAogICAgICAgICAgICAgIGNhc2UgMTM0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNDYKICAgICAgICAgICAgICBjYXNlIDEzNTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM1NAogICAgICAgICAgICAgIGNhc2UgMTM2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzYyCiAgICAgICAgICAgICAgY2FzZSAxMzcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNzAKICAgICAgICAgICAgICBjYXNlIDEzNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM3OAogICAgICAgICAgICAgIGNhc2UgMTM4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRG91YmxlMTczX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzg2CiAgICAgICAgICAgICAgY2FzZSAxMzk0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0X18gPSBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkTWFwVWludDMyRW51bTE3NF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMTc0LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyRW51bTE3NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM5NAogICAgICAgICAgICAgIGNhc2UgMTQwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDAyCiAgICAgICAgICAgICAgY2FzZSAxNDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MTAKICAgICAgICAgICAgICBjYXNlIDE0MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQxOAogICAgICAgICAgICAgIGNhc2UgMTQyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDMyMTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MjYKICAgICAgICAgICAgICBjYXNlIDE0MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDY0MTc5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMySW50NjQxNzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDM0CiAgICAgICAgICAgICAgY2FzZSAxNDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ0MgogICAgICAgICAgICAgIGNhc2UgMTQ1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NTAKICAgICAgICAgICAgICBjYXNlIDE0NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDU4CiAgICAgICAgICAgICAgY2FzZSAxNDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDY2CiAgICAgICAgICAgICAgY2FzZSAxNDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDc0CiAgICAgICAgICAgICAgY2FzZSAxNDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0ODIKICAgICAgICAgICAgICBjYXNlIDE0OTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0OTAKICAgICAgICAgICAgICBjYXNlIDE0OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0OTgKICAgICAgICAgICAgICBjYXNlIDE1MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRCb29sMTg4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUwNgogICAgICAgICAgICAgIGNhc2UgMTUxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTE0CiAgICAgICAgICAgICAgY2FzZSAxNTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MjIKICAgICAgICAgICAgICBjYXNlIDE1MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXyA9IEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBVaW50NjRFbnVtMTkxX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxOTEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRFbnVtMTkxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTMwCiAgICAgICAgICAgICAgY2FzZSAxNTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MzgKICAgICAgICAgICAgICBjYXNlIDE1NDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0NgogICAgICAgICAgICAgIGNhc2UgMTU1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGbG9hdDE5NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTU0CiAgICAgICAgICAgICAgY2FzZSAxNTYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEludDMyMTk1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU2MgogICAgICAgICAgICAgIGNhc2UgMTU3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDY0MTk2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NzAKICAgICAgICAgICAgICBjYXNlIDE1Nzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTc4CiAgICAgICAgICAgICAgY2FzZSAxNTg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU4NgogICAgICAgICAgICAgIGNhc2UgMTU5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1OTQKICAgICAgICAgICAgICBjYXNlIDE2MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MDIKICAgICAgICAgICAgICBjYXNlIDE2MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDY0MjAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MTAKICAgICAgICAgICAgICBjYXNlIDE2MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTdHJpbmcyMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYxOAogICAgICAgICAgICAgIGNhc2UgMTYyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50MzIyMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0VWludDMyMjAzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYyNgogICAgICAgICAgICAgIGNhc2UgMTYzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0VWludDY0MjA0X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0VWludDY0MjA0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYzNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMl87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkM187CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNl87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwQm9vbEJvb2wxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEJvb2wxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xCb29sMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEJvb2wxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfID0gZmllbGRNYXBCb29sQm9vbDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xCb29sMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xCb29sMSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xCb29sMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEJvb2xCeXRlczJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xCeXRlczJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sQnl0ZXMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xCeXRlczJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xCeXRlczJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJ5dGVzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEJ5dGVzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJ5dGVzMl8gPSBmaWVsZE1hcEJvb2xCeXRlczJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xCeXRlczJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQnl0ZXMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xCeXRlczIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbERvdWJsZTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRG91YmxlM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRG91YmxlM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sRG91YmxlM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xEb3VibGUzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sRG91YmxlM18gPSBmaWVsZE1hcEJvb2xEb3VibGUzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRG91YmxlM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xEb3VibGUzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xEb3VibGUzKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbERvdWJsZTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEJvb2xEb3VibGUzT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEJvb2xEb3VibGUzT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xFbnVtNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xFbnVtNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRW51bTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRW51bTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEVudW00XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xFbnVtNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEVudW00XyA9IGZpZWxkTWFwQm9vbEVudW00Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRW51bTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEVudW00TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xFbnVtNCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBCb29sRW51bTRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDMyNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDMyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRml4ZWQzMjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xGaXhlZDMyNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9IGZpZWxkTWFwQm9vbEZpeGVkMzI1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xGaXhlZDMyNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQ2NDZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEZpeGVkNjQ2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQ2NDZfID0gZmllbGRNYXBCb29sRml4ZWQ2NDZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGbG9hdDdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGbG9hdDdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEZsb2F0N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N18gPSBmaWVsZE1hcEJvb2xGbG9hdDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEludDMyOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sSW50MzI4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEludDMyOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEludDMyOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEludDMyOF8gPSBmaWVsZE1hcEJvb2xJbnQzMjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xJbnQzMjhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEludDY0OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDY0OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sSW50NjQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQ2NDlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xJbnQ2NDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQ2NDlfID0gZmllbGRNYXBCb29sSW50NjQ5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50NjQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDY0OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIgZmllbGRNYXBCb29sTWVzc2FnZTEwQ29udmVydGVyID0gbmV3IEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sTWVzc2FnZTEwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwQm9vbE1lc3NhZ2UxMEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTZml4ZWQzMjExXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkNjQxMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ludDMyMTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDMyMTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU2ludDMyMTNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM18gPSBmaWVsZE1hcEJvb2xTaW50MzIxM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNpbnQzMjEzKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTaW50NjQxNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50NjQxNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDY0MTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTaW50NjQxNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGZpZWxkTWFwQm9vbFNpbnQ2NDE0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTdHJpbmcxNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGZpZWxkTWFwQm9vbFN0cmluZzE1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU3RyaW5nMTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50MzIxNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sVWludDMyMTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xVaW50MzIxNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGZpZWxkTWFwQm9vbFVpbnQzMjE2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xVaW50MzIxNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFVpbnQ2NDE3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbFVpbnQ2NDE3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfID0gZmllbGRNYXBCb29sVWludDY0MTdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQm9vbDE4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCb29sMThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkJvb2wxOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBmaWVsZE1hcEZpeGVkMzJCb29sMThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJCb29sMThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJCb29sMTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJFbnVtMjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gZmllbGRNYXBGaXhlZDMyRW51bTIxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID0gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPSBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9IGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMkludDMyMjVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkludDMyMjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9IGZpZWxkTWFwRml4ZWQzMkludDMyMjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPSBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50NjQyNl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyID0gbmV3IEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPSBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID0gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9IGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDY0MzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9IGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPSBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfID0gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDMyMzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50NjQzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfID0gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDY0MzQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyVWludDY0MzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qm9vbDM1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCb29sMzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRCb29sMzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCb29sMzVfID0gZmllbGRNYXBGaXhlZDY0Qm9vbDM1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qm9vbDM1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9IGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjREb3VibGUzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjREb3VibGUzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfID0gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjREb3VibGUzNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0RW51bTM4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4XyA9IGZpZWxkTWFwRml4ZWQ2NEVudW0zOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDMyNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlciA9IG5ldyBGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID0gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0VWludDMyNTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0VWludDMyNTBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDY0NTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyQm9vbDUyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml8gPSBmaWVsZE1hcEludDMyQm9vbDUyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJ5dGVzNTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJ5dGVzNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCeXRlczUzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyQnl0ZXM1M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJCeXRlczUzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfID0gZmllbGRNYXBJbnQzMkJ5dGVzNTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJEb3VibGU1NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRG91YmxlNTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJEb3VibGU1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJEb3VibGU1NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBmaWVsZE1hcEludDMyRG91YmxlNTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRG91YmxlNTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRG91YmxlNTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRG91YmxlNTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJFbnVtNTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJFbnVtNTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkVudW01NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfID0gZmllbGRNYXBJbnQzMkVudW01NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkVudW01NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJFbnVtNTUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDMyRW51bTU1TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJFbnVtNTUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJFbnVtNTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDMyRW51bTU1TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQzMjU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyRml4ZWQzMjU2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8gPSBmaWVsZE1hcEludDMyRml4ZWQzMjU2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID0gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJGbG9hdDU4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGbG9hdDU4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZsb2F0NThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJGbG9hdDU4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyRmxvYXQ1OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJGbG9hdDU4XyA9IGZpZWxkTWFwSW50MzJGbG9hdDU4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRmxvYXQ1OCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMySW50MzI1OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkludDMyNTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMySW50MzI1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJJbnQzMjU5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkludDMyNTlfID0gZmllbGRNYXBJbnQzMkludDMyNTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50NjQ2MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMySW50NjQ2MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkludDY0NjBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMySW50NjQ2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJJbnQ2NDYwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkludDY0NjBfID0gZmllbGRNYXBJbnQzMkludDY0NjBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50NjQ2MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50NjQ2MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDY0NjAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkludDY0NjAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfID0gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID0gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50MzI2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDMyNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyU2ludDMyNjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDMyNjRfID0gZmllbGRNYXBJbnQzMlNpbnQzMjY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQzMjY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJTaW50NjQ2NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ludDY0NjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTaW50NjQ2NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPSBmaWVsZE1hcEludDMyU2ludDY0NjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU3RyaW5nNjZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTdHJpbmc2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTdHJpbmc2Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPSBmaWVsZE1hcEludDMyU3RyaW5nNjZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlVpbnQzMjY3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDMyNjdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJVaW50MzI2N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N18gPSBmaWVsZE1hcEludDMyVWludDMyNjdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDY0NjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlVpbnQ2NDY4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGZpZWxkTWFwSW50MzJVaW50NjQ2OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50NjQ2OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyVWludDY0NjhPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRCb29sNjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRCb29sNjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEJvb2w2OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfID0gZmllbGRNYXBJbnQ2NEJvb2w2OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Qnl0ZXM3MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRCeXRlczcwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEludDY0RG91YmxlNzFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjREb3VibGU3MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NERvdWJsZTcxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGZpZWxkTWFwSW50NjREb3VibGU3MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RW51bTcyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RW51bTcyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEVudW03MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRFbnVtNzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyXyA9IGZpZWxkTWFwSW50NjRFbnVtNzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RW51bTcyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDY0RW51bTcyTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50NjRFbnVtNzJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0RW51bTcyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDY0RW51bTcyTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0Rml4ZWQzMjczXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPSBmaWVsZE1hcEludDY0Rml4ZWQzMjczXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0Rml4ZWQ2NDc0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPSBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RmxvYXQ3NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZsb2F0NzVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGbG9hdDc1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RmxvYXQ3NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEZsb2F0NzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RmxvYXQ3NV8gPSBmaWVsZE1hcEludDY0RmxvYXQ3NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRJbnQzMjc2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0SW50MzI3Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEludDMyNzZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRJbnQzMjc2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEludDMyNzZfID0gZmllbGRNYXBJbnQ2NEludDMyNzZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDY0NzdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQ2NDc3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEludDY0NzdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N18gPSBmaWVsZE1hcEludDY0SW50NjQ3N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlciBmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyID0gbmV3IEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcEludDY0TWVzc2FnZTc4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0TWVzc2FnZTc4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0TWVzc2FnZTc4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0TWVzc2FnZTc4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0TWVzc2FnZTc4XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcEludDY0TWVzc2FnZTc4QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9IGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID0gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDMyODFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50MzI4MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTaW50MzI4MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50MzI4MV8gPSBmaWVsZE1hcEludDY0U2ludDMyODFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0U2ludDY0ODJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfID0gZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBJbnQ2NFN0cmluZzgzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U3RyaW5nODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U3RyaW5nODNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTdHJpbmc4M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPSBmaWVsZE1hcEludDY0U3RyaW5nODNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFN0cmluZzgzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFN0cmluZzgzKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFN0cmluZzgzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFVpbnQzMjg0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0VWludDMyODRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQzMjg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50MzI4NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQzMjg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFVpbnQzMjg0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9IGZpZWxkTWFwSW50NjRVaW50MzI4NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0VWludDY0ODVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRVaW50NjQ4NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV8gPSBmaWVsZE1hcEludDY0VWludDY0ODVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0VWludDY0ODUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRVaW50NjQ4NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0VWludDY0ODUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0VWludDY0ODUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJvb2w4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfID0gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XyA9IGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID0gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9IGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50MzI5M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50MzI5M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlciBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyID0gbmV3IEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9IGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID0gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPSBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPSBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID0gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJCb29sMTIwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyQm9vbDEyMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJvb2wxMjAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRW51bTEyM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJFbnVtMTIzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkVudW0xMjNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfID0gZmllbGRNYXBTaW50MzJFbnVtMTIzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID0gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPSBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGbG9hdDEyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGbG9hdDEyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyRmxvYXQxMjZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9IGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMySW50MzIxMjdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMySW50MzIxMjdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMySW50MzIxMjdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9IGZpZWxkTWFwU2ludDMySW50MzIxMjdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJJbnQzMjEyNygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJJbnQzMjEyNygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50NjQxMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkludDY0MTI4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8gPSBmaWVsZE1hcFNpbnQzMkludDY0MTI4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyID0gbmV3IEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPSBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID0gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTaW50MzIxMzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9IGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJTaW50MzIxMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTaW50NjQxMzNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9IGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPSBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyVWludDMyMTM1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfID0gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJVaW50MzIxMzUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJVaW50NjQxMzZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyVWludDY0MTM2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJVaW50NjQxMzZfID0gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJVaW50NjQxMzYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJVaW50NjQxMzYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJvb2wxMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qm9vbDEzN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRCb29sMTM3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJvb2wxMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfID0gZmllbGRNYXBTaW50NjRCb29sMTM3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCb29sMTM3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCb29sMTM3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRCb29sMTM3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRCb29sMTM3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCeXRlczEzOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCeXRlczEzOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCeXRlczEzOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XyA9IGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjREb3VibGUxMzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0RG91YmxlMTM5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjREb3VibGUxMzlfID0gZmllbGRNYXBTaW50NjREb3VibGUxMzlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRFbnVtMTQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RW51bTE0MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRFbnVtMTQwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRFbnVtMTQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRFbnVtMTQwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRFbnVtMTQwXyA9IGZpZWxkTWFwU2ludDY0RW51bTE0MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRFbnVtMTQwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID0gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9IGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPSBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRGbG9hdDE0MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50MzIxNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0SW50MzIxNDRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9IGZpZWxkTWFwU2ludDY0SW50MzIxNDRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0SW50NjQxNDVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9IGZpZWxkTWFwU2ludDY0SW50NjQxNDVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID0gZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID0gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID0gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRTaW50NjQxNTBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8gPSBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPSBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRVaW50MzIxNTJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPSBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9IGZpZWxkTWFwU2ludDY0VWludDY0MTUzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU3RyaW5nQm9vbDE1NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdCb29sMTU0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID0gZmllbGRNYXBTdHJpbmdCb29sMTU0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdCeXRlczE1NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdCeXRlczE1NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0J5dGVzMTU1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV8gPSBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdCeXRlczE1NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8gPSBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0VudW0xNTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRW51bTE1N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdFbnVtMTU3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9IGZpZWxkTWFwU3RyaW5nRW51bTE1N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9IGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID0gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPSBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGbG9hdDE2MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ludDMyMTYxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ludDY0MTYyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50NjQxNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID0gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlciBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID0gZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9IGZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9IGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQm9vbDE3MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJCb29sMTcxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGZpZWxkTWFwVWludDMyQm9vbDE3MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJCeXRlczE3Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID0gZmllbGRNYXBVaW50MzJCeXRlczE3Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRG91YmxlMTczXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRG91YmxlMTczKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyRW51bTE3NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkVudW0xNzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRW51bTE3NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF8gPSBmaWVsZE1hcFVpbnQzMkVudW0xNzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPSBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9IGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJGbG9hdDE3N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID0gZmllbGRNYXBVaW50MzJGbG9hdDE3N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJJbnQzMjE3OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMySW50MzIxNzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQzMjE3OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMySW50MzIxNzhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDMyMTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJJbnQzMjE3OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfID0gZmllbGRNYXBVaW50MzJJbnQzMjE3OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMySW50MzIxNzhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJJbnQzMjE3OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMySW50NjQxNzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMySW50NjQxNzlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMySW50NjQxNzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9IGZpZWxkTWFwVWludDMySW50NjQxNzlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50NjQxNzlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlciBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4gZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXyA9IGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPSBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDMyMTgzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU2ludDMyMTgzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfID0gZmllbGRNYXBVaW50MzJTaW50MzIxODNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTaW50MzIxODMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDY0MTg0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50NjQxODRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU2ludDY0MTg0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50NjQxODRfID0gZmllbGRNYXBVaW50MzJTaW50NjQxODRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTaW50NjQxODQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJTaW50NjQxODQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XyA9IGZpZWxkTWFwVWludDMyU3RyaW5nMTg1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJVaW50MzIxODZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50MzIxODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDMyMTg2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJVaW50MzIxODZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPSBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDMyMTg2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJVaW50NjQxODdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDY0MTg3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJVaW50NjQxODdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPSBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDY0MTg3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwVWludDY0Qm9vbDE4OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRCb29sMTg4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCb29sMTg4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJvb2wxODhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0Qm9vbDE4OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPSBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRCeXRlczE4OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfID0gZmllbGRNYXBVaW50NjRCeXRlczE4OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRCeXRlczE4OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRCeXRlczE4OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjREb3VibGUxOTBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8gPSBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RW51bTE5MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEVudW0xOTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID0gZmllbGRNYXBVaW50NjRFbnVtMTkxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEVudW0xOTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPSBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID0gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGbG9hdDE5NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0RmxvYXQxOTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50MzIxOTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50MzIxOTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRJbnQzMjE5NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfID0gZmllbGRNYXBVaW50NjRJbnQzMjE5NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50MzIxOTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50NjQxOTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQ2NDE5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50NjQxOTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfID0gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50NjQxOTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyID0gbmV3IEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0J1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8gPSBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8gPSBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50MzIyMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRTaW50MzIyMDBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPSBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50NjQyMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9IGZpZWxkTWFwVWludDY0U2ludDY0MjAxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTdHJpbmcyMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTdHJpbmcyMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXyA9IGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50MzIyMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzXyA9IGZpZWxkTWFwVWludDY0VWludDMyMjAzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0VWludDMyMjAzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0VWludDMyMjAzKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0VWludDY0MjA0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID0gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJNZXNzYWdlV2l0aE1hcHM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8yTWVzc2FnZVdpdGhNYXBzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUHJvdG8yTWVzc2FnZVdpdGhNYXBzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZVdpdGhNYXBzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMk1lc3NhZ2VXaXRoTWFwcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZERvdWJsZTEgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfMl9GSUVMRF9OVU1CRVIgPSAyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkZsb2F0PiBmaWVsZEZsb2F0MiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkZsb2F0LmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0XzNfRklFTERfTlVNQkVSID0gMzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBmaWVsZEludDY0MyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0XzRfRklFTERfTlVNQkVSID0gNDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBmaWVsZFVpbnQ2NDQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyXzVfRklFTERfTlVNQkVSID0gNTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEludDMyNSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF82X0ZJRUxEX05VTUJFUiA9IDY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuTG9uZz4gZmllbGRGaXhlZDY0NiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl83X0ZJRUxEX05VTUJFUiA9IDc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRGaXhlZDMyNyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF84X0ZJRUxEX05VTUJFUiA9IDg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRCb29sOCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU1RSSU5HXzlfRklFTERfTlVNQkVSID0gOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkU3RyaW5nOSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFXzEwX0ZJRUxEX05VTUJFUiA9IDEwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZT4gZmllbGRNZXNzYWdlMTAgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuY2xhc3MsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQllURVNfMTFfRklFTERfTlVNQkVSID0gMTE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkQnl0ZXMxMSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl8xMl9GSUVMRF9OVU1CRVIgPSAxMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZFVpbnQzMjEyID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9FTlVNXzEzX0ZJRUxEX05VTUJFUiA9IDEzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5UZXN0RW51bT4gZmllbGRFbnVtMTMgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSID0gMTQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRTZml4ZWQzMjE0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF8xNV9GSUVMRF9OVU1CRVIgPSAxNTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBmaWVsZFNmaXhlZDY0MTUgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZFNpbnQzMjE2ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UNjRfMTdfRklFTERfTlVNQkVSID0gMTc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuTG9uZz4gZmllbGRTaW50NjQxNyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFX0xJU1RfMThfRklFTERfTlVNQkVSID0gMTg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPj4gZmllbGREb3VibGVMaXN0MTggPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfTElTVF8xOV9GSUVMRF9OVU1CRVIgPSAxOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4+IGZpZWxkRmxvYXRMaXN0MTkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5GbG9hdC5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF9MSVNUXzIwX0ZJRUxEX05VTUJFUiA9IDIwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiBmaWVsZEludDY0TGlzdDIwID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UNjRfTElTVF8yMV9GSUVMRF9OVU1CRVIgPSAyMTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRVaW50NjRMaXN0MjEgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyX0xJU1RfMjJfRklFTERfTlVNQkVSID0gMjI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkSW50MzJMaXN0MjIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfTElTVF8yM19GSUVMRF9OVU1CRVIgPSAyMzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRGaXhlZDY0TGlzdDIzID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyX0xJU1RfMjRfRklFTERfTlVNQkVSID0gMjQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkRml4ZWQzMkxpc3QyNCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF9MSVNUXzI1X0ZJRUxEX05VTUJFUiA9IDI1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+PiBmaWVsZEJvb2xMaXN0MjUgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NUUklOR19MSVNUXzI2X0ZJRUxEX05VTUJFUiA9IDI2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4+IGZpZWxkU3RyaW5nTGlzdDI2ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01FU1NBR0VfTElTVF8yN19GSUVMRF9OVU1CRVIgPSAyNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2U+PiBmaWVsZE1lc3NhZ2VMaXN0MjcgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuY2xhc3MsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQllURVNfTElTVF8yOF9GSUVMRF9OVU1CRVIgPSAyODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4+IGZpZWxkQnl0ZXNMaXN0MjggPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfTElTVF8yOV9GSUVMRF9OVU1CRVIgPSAyOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRVaW50MzJMaXN0MjkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fTElTVF8zMF9GSUVMRF9OVU1CRVIgPSAzMDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0+PiBmaWVsZEVudW1MaXN0MzAgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2UuVGVzdEVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfTElTVF8zMV9GSUVMRF9OVU1CRVIgPSAzMTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRTZml4ZWQzMkxpc3QzMSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfTElTVF8zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRTZml4ZWQ2NExpc3QzMiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDMyX0xJU1RfMzNfRklFTERfTlVNQkVSID0gMzM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkU2ludDMyTGlzdDMzID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UNjRfTElTVF8zNF9GSUVMRF9OVU1CRVIgPSAzNDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRTaW50NjRMaXN0MzQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUX1BBQ0tFRF8zNV9GSUVMRF9OVU1CRVIgPSAzNTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+PiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF9MSVNUX1BBQ0tFRF8zNl9GSUVMRF9OVU1CRVIgPSAzNjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4+IGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5GbG9hdC5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF9MSVNUX1BBQ0tFRF8zN19GSUVMRF9OVU1CRVIgPSAzNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRJbnQ2NExpc3RQYWNrZWQzNyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfUEFDS0VEXzM4X0ZJRUxEX05VTUJFUiA9IDM4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfTElTVF9QQUNLRURfMzlfRklFTERfTlVNQkVSID0gMzk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkSW50MzJMaXN0UGFja2VkMzkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfTElTVF9QQUNLRURfNDBfRklFTERfTlVNQkVSID0gNDA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl9MSVNUX1BBQ0tFRF80MV9GSUVMRF9OVU1CRVIgPSA0MTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MX0xJU1RfUEFDS0VEXzQyX0ZJRUxEX05VTUJFUiA9IDQyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+PiBmaWVsZEJvb2xMaXN0UGFja2VkNDIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9MSVNUX1BBQ0tFRF80M19GSUVMRF9OVU1CRVIgPSA0MzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRVaW50MzJMaXN0UGFja2VkNDMgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fTElTVF9QQUNLRURfNDRfRklFTERfTlVNQkVSID0gNDQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtPj4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyX0xJU1RfUEFDS0VEXzQ1X0ZJRUxEX05VTUJFUiA9IDQ1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF9MSVNUX1BBQ0tFRF80Nl9GSUVMRF9OVU1CRVIgPSA0NjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDMyX0xJU1RfUEFDS0VEXzQ3X0ZJRUxEX05VTUJFUiA9IDQ3OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0X0xJU1RfUEFDS0VEXzQ4X0ZJRUxEX05VTUJFUiA9IDQ4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERHUk9VUDQ5X0ZJRUxEX05VTUJFUiA9IDQ5OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cDQ5PiBmaWVsZEdyb3VwNDkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nLkZpZWxkR3JvdXA0OS5jbGFzcywKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxER1JPVVBMSVNUNTFfRklFTERfTlVNQkVSID0gNTE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxPj4gZmllbGRHcm91cExpc3Q1MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmcuRmllbGRHcm91cExpc3Q1MS5jbGFzcywKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZy5GaWVsZEdyb3VwTGlzdDUxLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA0OV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNDlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cExpc3Q1MV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cDY5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA2OV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfUmVxdWlyZWROZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX1JlcXVpcmVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRSZXF1aXJlZEdyb3VwODhfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRSZXF1aXJlZEdyb3VwODhfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJFbXB0eV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yRW1wdHlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX0ZpZWxkR3JvdXA0OV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cDQ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cExpc3Q1MV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQnl0ZXMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEVudW00RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50MzI4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDY0MTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDY0MTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDMyMzBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDMyMzNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RW51bTM4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50NjQ0OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJ5dGVzNTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRG91YmxlNTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQzMjU2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQzMjU2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGbG9hdDU4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50NjQ2MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50MzI2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQ2NDY1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU3RyaW5nNjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQ2NDY4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJvb2w2OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJvb2w2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCeXRlczcwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NERvdWJsZTcxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEVudW03MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEVudW03MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50MzI5M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCb29sMTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCeXRlczEyMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCeXRlczEyMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRW51bTEyM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQzMjE0NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQzMjE0NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDMyMTUyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDY0MTUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCeXRlczE3MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCeXRlczE3MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RW51bTE5MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDMyMjAwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDY0MjAxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDMyMjAzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDY0MjA0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbihjb20vZ29vZ2xlL3Byb3RvYnVmL3Byb3RvMl9tZXNzYWdlLnBybyIgKwogICAgICAidG9cMDIyXDAyNXByb3RvYnVmLmV4cGVyaW1lbnRhbFwia1xuXDAyNlByb3RvMlNwZWNpIiArCiAgICAgICJhbEZpZWxkTmFtZVwwMjJcMDI0XG5cMDE0cmVndWxhcl9uYW1lXDAzMFwwMDEgXDAwMShcMDAxXDAyMlwwMjNcblwwMTNjYWMiICsKICAgICAgImhlZF9zaXplXDAzMFwwMDIgXDAwMShcMDA1XDAyMlwwMjdcblwwMTdzZXJpYWxpemVkX3NpemVcMDMwXDAwMyBcMDAxKFwwMDNcMDIyIiArCiAgICAgICJcclxuXDAwNWNsYXNzXDAzMFwwMDQgXDAwMShcdFwiXDMyMFwwMzNcblxyUHJvdG8yTWVzc2FnZVwwMjJcMDI2XG5cMDE2ZmllbCIgKwogICAgICAiZF9kb3VibGVfMVwwMzBcMDAxIFwwMDEoXDAwMVwwMjJcMDI1XG5ccmZpZWxkX2Zsb2F0XzJcMDMwXDAwMiBcMDAxKFwwMDJcMDIyIiArCiAgICAgICJcMDI1XG5ccmZpZWxkX2ludDY0XzNcMDMwXDAwMyBcMDAxKFwwMDNcMDIyXDAyNlxuXDAxNmZpZWxkX3VpbnQ2NF80IiArCiAgICAgICJcMDMwXDAwNCBcMDAxKFwwMDRcMDIyXDAyNVxuXHJmaWVsZF9pbnQzMl81XDAzMFwwMDUgXDAwMShcMDA1XDAyMlwwMjdcblwwMTdmaWVsZF9mIiArCiAgICAgICJpeGVkNjRfNlwwMzBcMDA2IFwwMDEoXDAwNlwwMjJcMDI3XG5cMDE3ZmllbGRfZml4ZWQzMl83XDAzMFwwMDcgXDAwMShcMDA3XDAyMiIgKwogICAgICAiXDAyNFxuXDAxNGZpZWxkX2Jvb2xfOFwwMzBcMDEwIFwwMDEoXDAxMFwwMjJcMDI2XG5cMDE2ZmllbGRfc3RyaW5nXzlcMDMwIiArCiAgICAgICJcdCBcMDAxKFx0XDAyMj5cblwwMjBmaWVsZF9tZXNzYWdlXzEwXDAzMFxuIFwwMDEoXDAxMzIkLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VcMDIyXDAyNlxuXDAxNmZpZWxkX2IiICsKICAgICAgInl0ZXNfMTFcMDMwXDAxMyBcMDAxKFwwMTRcMDIyXDAyN1xuXDAxN2ZpZWxkX3VpbnQzMl8xMlwwMzBcMDE0IFwwMDEoXHJcMDIyRCIgKwogICAgICAiXG5ccmZpZWxkX2VudW1fMTNcMDMwXHIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbSIgKwogICAgICAiZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bVwwMjJcMDMxXG5cMDIxZmllbGRfc2YiICsKICAgICAgIml4ZWQzMl8xNFwwMzBcMDE2IFwwMDEoXDAxN1wwMjJcMDMxXG5cMDIxZmllbGRfc2ZpeGVkNjRfMTVcMDMwXDAxNyBcMDAxIiArCiAgICAgICIoXDAyMFwwMjJcMDI3XG5cMDE3ZmllbGRfc2ludDMyXzE2XDAzMFwwMjAgXDAwMShcMDIxXDAyMlwwMjdcblwwMTdmaWVsZF9zaW4iICsKICAgICAgInQ2NF8xN1wwMzBcMDIxIFwwMDEoXDAyMlwwMjIgXG5cMDI0ZmllbGRfZG91YmxlX2xpc3RfMThcMDMwXDAyMiBcMDAzIiArCiAgICAgICIoXDAwMUJcMDAyXDAyMFwwMDBcMDIyXDAzN1xuXDAyM2ZpZWxkX2Zsb2F0X2xpc3RfMTlcMDMwXDAyMyBcMDAzKFwwMDJCXDAwMlwwMjBcMDAwXDAyMiIgKwogICAgICAiXDAzN1xuXDAyM2ZpZWxkX2ludDY0X2xpc3RfMjBcMDMwXDAyNCBcMDAzKFwwMDNCXDAwMlwwMjBcMDAwXDAyMiBcblwwMjRmaWVsIiArCiAgICAgICJkX3VpbnQ2NF9saXN0XzIxXDAzMFwwMjUgXDAwMyhcMDA0QlwwMDJcMDIwXDAwMFwwMjJcMDM3XG5cMDIzZmllbGRfaW50MyIgKwogICAgICAiMl9saXN0XzIyXDAzMFwwMjYgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMFwwMjIhXG5cMDI1ZmllbGRfZml4ZWQ2NF9saXMiICsKICAgICAgInRfMjNcMDMwXDAyNyBcMDAzKFwwMDZCXDAwMlwwMjBcMDAwXDAyMiFcblwwMjVmaWVsZF9maXhlZDMyX2xpc3RfMjRcMDMwIiArCiAgICAgICJcMDMwIFwwMDMoXDAwN0JcMDAyXDAyMFwwMDBcMDIyXDAzNlxuXDAyMmZpZWxkX2Jvb2xfbGlzdF8yNVwwMzBcMDMxIFwwMDMoXDAxMEJcMDAyXDAyMCIgKwogICAgICAiXDAwMFwwMjIgXG5cMDI0ZmllbGRfc3RyaW5nX2xpc3RfMjZcMDMwXDAzMiBcMDAzKFx0QlwwMDJcMDIwXDAwMFwwMjJHXG5cMDI1ZiIgKwogICAgICAiaWVsZF9tZXNzYWdlX2xpc3RfMjdcMDMwXDAzMyBcMDAzKFwwMTMyJC5wcm90b2J1Zi5leCIgKwogICAgICAicGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlQlwwMDJcMDIwXDAwMFwwMjJcMDM3XG5cMDIzZmllbGRfYnkiICsKICAgICAgInRlc19saXN0XzI4XDAzMFwwMzQgXDAwMyhcMDE0QlwwMDJcMDIwXDAwMFwwMjIgXG5cMDI0ZmllbGRfdWludDMyX2xpIiArCiAgICAgICJzdF8yOVwwMzBcMDM1IFwwMDMoXHJCXDAwMlwwMjBcMDAwXDAyMk1cblwwMjJmaWVsZF9lbnVtX2xpc3RfMzBcMDMwXDAzNiAiICsKICAgICAgIlwwMDMoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImUuVGVzdEVudW1CXDAwMlwwMjBcMDAwXDAyMlwiXG5cMDI2ZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSIgKwogICAgICAiXDAzMFwwMzcgXDAwMyhcMDE3QlwwMDJcMDIwXDAwMFwwMjJcIlxuXDAyNmZpZWxkX3NmaXhlZDY0X2xpc3RfMzJcMDMwICBcMDAzIiArCiAgICAgICIoXDAyMEJcMDAyXDAyMFwwMDBcMDIyIFxuXDAyNGZpZWxkX3NpbnQzMl9saXN0XzMzXDAzMCEgXDAwMyhcMDIxQlwwMDJcMDIwXDAwMCIgKwogICAgICAiXDAyMiBcblwwMjRmaWVsZF9zaW50NjRfbGlzdF8zNFwwMzBcIiBcMDAzKFwwMjJCXDAwMlwwMjBcMDAwXDAyMlwnXG5cMDMzZmkiICsKICAgICAgImVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzVcMDMwIyBcMDAzKFwwMDFCXDAwMlwwMjBcMDAxXDAyMiZcblwwMzJmIiArCiAgICAgICJpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2XDAzMCQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMVwwMjImXG5cMDMyZiIgKwogICAgICAiaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zN1wwMzAlIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXCdcblwwMzNmIiArCiAgICAgICJpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOFwwMzAmIFwwMDMoXDAwNEJcMDAyXDAyMFwwMDFcMDIyJlxuXDAzMiIgKwogICAgICAiZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzlcMDMwXCcgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjIoXG5cMDM0IiArCiAgICAgICJmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwXDAzMCggXDAwMyhcMDA2QlwwMDJcMDIwXDAwMVwwMjIoIiArCiAgICAgICJcblwwMzRmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxXDAzMCkgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMSIgKwogICAgICAiXDAyMiVcblwwMzFmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyXDAzMCogXDAwMyhcMDEwQlwwMDJcMDIwXDAwMVwwMjIiICsKICAgICAgIlwnXG5cMDMzZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzXDAzMCsgXDAwMyhcckJcMDAyXDAyMFwwMDEiICsKICAgICAgIlwwMjJUXG5cMDMxZmllbGRfZW51bV9saXN0X3BhY2tlZF80NFwwMzAsIFwwMDMoXDAxNjItLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuVGVzdEVuIiArCiAgICAgICJ1bUJcMDAyXDAyMFwwMDFcMDIyKVxuXDAzNWZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1XDAzMCIgKwogICAgICAiLSBcMDAzKFwwMTdCXDAwMlwwMjBcMDAxXDAyMilcblwwMzVmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF8iICsKICAgICAgIjQ2XDAzMC4gXDAwMyhcMDIwQlwwMDJcMDIwXDAwMVwwMjJcJ1xuXDAzM2ZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZCIgKwogICAgICAiXzQ3XDAzMC8gXDAwMyhcMDIxQlwwMDJcMDIwXDAwMVwwMjJcJ1xuXDAzM2ZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlIiArCiAgICAgICJkXzQ4XDAzMDAgXDAwMyhcMDIyQlwwMDJcMDIwXDAwMVwwMjJHXG5cMDE0ZmllbGRncm91cDQ5XDAzMDEgXDAwMShcbjIxLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UuRmllbGQiICsKICAgICAgIkdyb3VwNDlcMDIyT1xuXDAyMGZpZWxkZ3JvdXBsaXN0NTFcMDMwMyBcMDAzKFxuMjUucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdybyIgKwogICAgICAidXBMaXN0NTFcMDIyXDAzMVxuXDAxN2ZpZWxkX2RvdWJsZV81M1wwMzA1IFwwMDEoXDAwMUhcMDAwXDAyMlwwMzBcblwwMTZmIiArCiAgICAgICJpZWxkX2Zsb2F0XzU0XDAzMDYgXDAwMShcMDAySFwwMDBcMDIyXDAzMFxuXDAxNmZpZWxkX2ludDY0XzU1XDAzMCIgKwogICAgICAiNyBcMDAxKFwwMDNIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfdWludDY0XzU2XDAzMDggXDAwMShcMDA0SFwwMDBcMDIyXDAzMFxuXDAxNmZpIiArCiAgICAgICJlbGRfaW50MzJfNTdcMDMwOSBcMDAxKFwwMDVIXDAwMFwwMjJcMDMyXG5cMDIwZmllbGRfZml4ZWQ2NF81OCIgKwogICAgICAiXDAzMDogXDAwMShcMDA2SFwwMDBcMDIyXDAzMlxuXDAyMGZpZWxkX2ZpeGVkMzJfNTlcMDMwOyBcMDAxKFwwMDdIXDAwMFwwMjJcMDI3XG5cciIgKwogICAgICAiZmllbGRfYm9vbF82MFwwMzA8IFwwMDEoXDAxMEhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF9zdHJpbmdfNjEiICsKICAgICAgIlwwMzA9IFwwMDEoXHRIXDAwMFwwMjJAXG5cMDIwZmllbGRfbWVzc2FnZV82MlwwMzA+IFwwMDEoXDAxMzIkLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VIXDAwMFwwMjJcMDMwXG5cMDE2ZmkiICsKICAgICAgImVsZF9ieXRlc182M1wwMzA/IFwwMDEoXDAxNEhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF91aW50MzJfNjRcMDMwIiArCiAgICAgICJAIFwwMDEoXHJIXDAwMFwwMjJcMDMzXG5cMDIxZmllbGRfc2ZpeGVkMzJfNjVcMDMwQSBcMDAxKFwwMTdIXDAwMFwwMjJcMDMzXG5cMDIxIiArCiAgICAgICJmaWVsZF9zZml4ZWQ2NF82NlwwMzBCIFwwMDEoXDAyMEhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF9zaW50MyIgKwogICAgICAiMl82N1wwMzBDIFwwMDEoXDAyMUhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF9zaW50NjRfNjhcMDMwRCBcMDAxKFwwMjJIXDAwMFwwMjIiICsKICAgICAgIklcblwwMTRmaWVsZGdyb3VwNjlcMDMwRSBcMDAxKFxuMjEucHJvdG9idWYuZXhwZXJpbSIgKwogICAgICAiZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZEdyb3VwNjlIXDAwMFwwMjIgXG5cMDMwZmkiICsKICAgICAgImVsZF9yZXF1aXJlZF9kb3VibGVfNzFcMDMwRyBcMDAyKFwwMDFcMDIyXDAzN1xuXDAyN2ZpZWxkX3JlIiArCiAgICAgICJxdWlyZWRfZmxvYXRfNzJcMDMwSCBcMDAyKFwwMDJcMDIyXDAzN1xuXDAyN2ZpZWxkX3JlcXVpcmVkXyIgKwogICAgICAiaW50NjRfNzNcMDMwSSBcMDAyKFwwMDNcMDIyIFxuXDAzMGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF8iICsKICAgICAgIjc0XDAzMEogXDAwMihcMDA0XDAyMlwwMzdcblwwMjdmaWVsZF9yZXF1aXJlZF9pbnQzMl83NVwwMzBLIFwwMDIoIiArCiAgICAgICJcMDA1XDAyMiFcblwwMzFmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2XDAzMEwgXDAwMihcMDA2XDAyMiFcblwwMzEiICsKICAgICAgImZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzdcMDMwTSBcMDAyKFwwMDdcMDIyXDAzNlxuXDAyNmZpZWxkIiArCiAgICAgICJfcmVxdWlyZWRfYm9vbF83OFwwMzBOIFwwMDIoXDAxMFwwMjIgXG5cMDMwZmllbGRfcmVxdWlyZSIgKwogICAgICAiZF9zdHJpbmdfNzlcMDMwTyBcMDAyKFx0XDAyMl1cblwwMzFmaWVsZF9yZXF1aXJlZF9tZXNzIiArCiAgICAgICJhZ2VfODBcMDMwUCBcMDAyKFwwMTMyOi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZVwwMjJcMDM3XG5cMDI3ZmllbCIgKwogICAgICAiZF9yZXF1aXJlZF9ieXRlc184MVwwMzBRIFwwMDIoXDAxNFwwMjIgXG5cMDMwZmllbGRfcmVxdWkiICsKICAgICAgInJlZF91aW50MzJfODJcMDMwUiBcMDAyKFxyXDAyMk1cblwwMjZmaWVsZF9yZXF1aXJlZF9lbiIgKwogICAgICAidW1fODNcMDMwUyBcMDAyKFwwMTYyLS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdCIgKwogICAgICAibzJNZXNzYWdlLlRlc3RFbnVtXDAyMlwiXG5cMDMyZmllbGRfcmVxdWlyZWRfc2ZpIiArCiAgICAgICJ4ZWQzMl84NFwwMzBUIFwwMDIoXDAxN1wwMjJcIlxuXDAzMmZpZWxkX3JlcXVpcmVkX3NmaXhlZDYiICsKICAgICAgIjRfODVcMDMwVSBcMDAyKFwwMjBcMDIyIFxuXDAzMGZpZWxkX3JlcXVpcmVkX3NpbnQzMl84NlwwMzBWIiArCiAgICAgICIgXDAwMihcMDIxXDAyMiBcblwwMzBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODdcMDMwVyBcMDAyKFwwMjJcMDIyVyIgKwogICAgICAiXG5cMDI0ZmllbGRyZXF1aXJlZGdyb3VwODhcMDMwWCBcMDAyKFxuMjkucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5GaWVsZFJlcXVpcmVkIiArCiAgICAgICJHcm91cDg4XDAzMiZcblwwMTRGaWVsZEdyb3VwNDlcMDIyXDAyNlxuXDAxNmZpZWxkX2ludDMyXzUiICsKICAgICAgIjBcMDMwMiBcMDAxKFwwMDVcMDMyKlxuXDAyMEZpZWxkR3JvdXBMaXN0NTFcMDIyXDAyNlxuXDAxNmZpZWxkX2ludCIgKwogICAgICAiMzJfNTJcMDMwNCBcMDAxKFwwMDVcMDMyJlxuXDAxNEZpZWxkR3JvdXA2OVwwMjJcMDI2XG5cMDE2ZmllbGRfaW50IiArCiAgICAgICIzMl83MFwwMzBGIFwwMDEoXDAwNVwwMzImXG5cMDI1UmVxdWlyZWROZXN0ZWRNZXNzYWdlXDAyMlxyXG5cMDA1IiArCiAgICAgICJ2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNVwwMzIuXG5cMDI0RmllbGRSZXF1aXJlZEdyb3VwODhcMDIyXDAyNlxuXDAxNmYiICsKICAgICAgImllbGRfaW50MzJfODlcMDMwWSBcMDAxKFwwMDVcIiZcblwwMTBUZXN0RW51bVwwMjJcMDEwXG5cMDA0WkVST1wwMjAiICsKICAgICAgIlwwMDBcMDIyXDAwN1xuXDAwM09ORVwwMjBcMDAxXDAyMlwwMDdcblwwMDNUV09cMDIwXDAwMkJcMDE0XG5cbnRlc3Rfb25lb2ZcIlxyXG5cMDEzUHJvIiArCiAgICAgICJ0bzJFbXB0eVwiJFxuXDAzM1Byb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyoiICsKICAgICAgIlwwMDVcMDEwXDAwMVwwMjBcMjIxTlwiJlxuXDAxNEZpZWxkR3JvdXA0OVwwMjJcMDI2XG5cMDE2ZmllbGRfaW50MzJfNTAiICsKICAgICAgIlwwMzAyIFwwMDEoXDAwNVwiKlxuXDAyMEZpZWxkR3JvdXBMaXN0NTFcMDIyXDAyNlxuXDAxNmZpZWxkX2ludDMiICsKICAgICAgIjJfNTJcMDMwNCBcMDAxKFwwMDVcIlwyMzZcMjM3XDAwMlxuXDAyNVByb3RvMk1lc3NhZ2VXaXRoTWFwc1wwMjJiXG4iICsKICAgICAgIlwwMjVmaWVsZF9tYXBfYm9vbF9ib29sXzFcMDMwXDAwMSBcMDAzKFwwMTMyQy5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGQiICsKICAgICAgIk1hcEJvb2xCb29sMUVudHJ5XDAyMmRcblwwMjZmaWVsZF9tYXBfYm9vbF9ieXRlIiArCiAgICAgICJzXzJcMDMwXDAwMiBcMDAzKFwwMTMyRC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yIiArCiAgICAgICJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBCb29sQnl0ZXMyRW50cnlcMDIyIiArCiAgICAgICJmXG5cMDI3ZmllbGRfbWFwX2Jvb2xfZG91YmxlXzNcMDMwXDAwMyBcMDAzKFwwMTMyRS5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcEJvb2xEb3VibGUzRW50cnlcMDIyYlxuXDAyNWZpZWxkX21hcF9ib28iICsKICAgICAgImxfZW51bV80XDAzMFwwMDQgXDAwMyhcMDEzMkMucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEVudW00RW4iICsKICAgICAgInRyeVwwMjJoXG5cMDMwZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81XDAzMFwwMDUgXDAwMyhcMDEzMkYuIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNIiArCiAgICAgICJhcHMuRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeVwwMjJoXG5cMDMwZmllbGRfbSIgKwogICAgICAiYXBfYm9vbF9maXhlZDY0XzZcMDMwXDAwNiBcMDAzKFwwMTMyRi5wcm90b2J1Zi5leHBlciIgKwogICAgICAiaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBCbyIgKwogICAgICAib2xGaXhlZDY0NkVudHJ5XDAyMmRcblwwMjZmaWVsZF9tYXBfYm9vbF9mbG9hdF8iICsKICAgICAgIjdcMDMwXDAwNyBcMDAzKFwwMTMyRC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWUiICsKICAgICAgInNzYWdlV2l0aE1hcHMuRmllbGRNYXBCb29sRmxvYXQ3RW50cnlcMDIyZFxuIiArCiAgICAgICJcMDI2ZmllbGRfbWFwX2Jvb2xfaW50MzJfOFwwMzBcMDEwIFwwMDMoXDAxMzJELnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwQm9vbEludDMyOEVudHJ5XDAyMmRcblwwMjZmaWVsZF9tYXBfYm9vbF9pbiIgKwogICAgICAidDY0XzlcMDMwXHQgXDAwMyhcMDEzMkQucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3QiICsKICAgICAgIm8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEludDY0OUVudHIiICsKICAgICAgInlcMDIyalxuXDAzMWZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTBcMDMwXG4gXDAwMyhcMDEzMkcucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlcMDIybFxuXDAzMmZpZWxkX20iICsKICAgICAgImFwX2Jvb2xfc2ZpeGVkMzJfMTFcMDMwXDAxMyBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIkJvb2xTZml4ZWQzMjExRW50cnlcMDIybFxuXDAzMmZpZWxkX21hcF9ib29sX3NmIiArCiAgICAgICJpeGVkNjRfMTJcMDMwXDAxNCBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBCb29sU2ZpeGVkIiArCiAgICAgICI2NDEyRW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9ib29sX3NpbnQzMl8xM1wwMzBcciAiICsKICAgICAgIlwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5XDAyMmhcblwwMzBmIiArCiAgICAgICJpZWxkX21hcF9ib29sX3NpbnQ2NF8xNFwwMzBcMDE2IFwwMDMoXDAxMzJGLnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwQm9vbFNpbnQ2NDE0RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9ib29sXyIgKwogICAgICAic3RyaW5nXzE1XDAzMFwwMTcgXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbFN0cmluZyIgKwogICAgICAiMTVFbnRyeVwwMjJoXG5cMDMwZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2XDAzMFwwMjAgXDAwMygiICsKICAgICAgIlwwMTMyRi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBCb29sVWludDMyMTZFbnRyeVwwMjJoXG5cMDMwZmllIiArCiAgICAgICJsZF9tYXBfYm9vbF91aW50NjRfMTdcMDMwXDAyMSBcMDAzKFwwMTMyRi5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcEJvb2xVaW50NjQxN0VudHJ5XDAyMmpcblwwMzFmaWVsZF9tYXBfZml4ZWQzMiIgKwogICAgICAiX2Jvb2xfMThcMDMwXDAyMiBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyQm9vbCIgKwogICAgICAiMThFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTlcMDMwXDAyMyAiICsKICAgICAgIlwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJCeXRlczE5RW50cnlcMDIyblxuIiArCiAgICAgICJcMDMzZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwXDAzMFwwMjQgXDAwMyhcMDEzMkkucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIiArCiAgICAgICIuRmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbnRyeVwwMjJqXG5cMDMxZmllbGRfbSIgKwogICAgICAiYXBfZml4ZWQzMl9lbnVtXzIxXDAzMFwwMjUgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRiIgKwogICAgICAiaXhlZDMyRW51bTIxRW50cnlcMDIycFxuXDAzNGZpZWxkX21hcF9maXhlZDMyX2YiICsKICAgICAgIml4ZWQzMl8yMlwwMzBcMDI2IFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJGaXgiICsKICAgICAgImVkMzIyMkVudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0IiArCiAgICAgICJfMjNcMDMwXDAyNyBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yIiArCiAgICAgICJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzIiArCiAgICAgICJFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjRcMDMwXDAzMCBcMDAzKCIgKwogICAgICAiXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlVyIgKwogICAgICAiaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlcMDIybFxuXDAzMmYiICsKICAgICAgImllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjVcMDMwXDAzMSBcMDAzKFwwMTMySC5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmkiICsKICAgICAgImVsZE1hcEZpeGVkMzJJbnQzMjI1RW50cnlcMDIybFxuXDAzMmZpZWxkX21hcF9mIiArCiAgICAgICJpeGVkMzJfaW50NjRfMjZcMDMwXDAzMiBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlIiArCiAgICAgICJkMzJJbnQ2NDI2RW50cnlcMDIycFxuXDAzNGZpZWxkX21hcF9maXhlZDMyX21lcyIgKwogICAgICAic2FnZV8yN1wwMzBcMDMzIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QciIgKwogICAgICAib3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJNZXNzYSIgKwogICAgICAiZ2UyN0VudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8iICsKICAgICAgIjI4XDAzMFwwMzQgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk0iICsKICAgICAgImVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgiICsKICAgICAgIkVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOVwwMzBcMDM1IiArCiAgICAgICIgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhIiArCiAgICAgICJnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyIiArCiAgICAgICJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzBcMDMwXDAzNiBcMDAzKFwwMTMySSIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aCIgKwogICAgICAiTWFwcy5GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5XDAyMm5cblwwMzNmaWUiICsKICAgICAgImxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMVwwMzBcMDM3IFwwMDMoXDAxMzJJLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlcMDIyblxuXDAzM2ZpZWxkX21hcF9mIiArCiAgICAgICJpeGVkMzJfc3RyaW5nXzMyXDAzMCAgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4IiArCiAgICAgICJlZDMyU3RyaW5nMzJFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX2ZpeGVkMzJfdSIgKwogICAgICAiaW50MzJfMzNcMDMwISBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyVWludCIgKwogICAgICAiMzIzM0VudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQiICsKICAgICAgIlwwMzBcIiBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyIiArCiAgICAgICJ5XDAyMmpcblwwMzFmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1XDAzMCMgXDAwMyhcMDEzMkcucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlcMDIybFxuXDAzMmZpZWxkX20iICsKICAgICAgImFwX2ZpeGVkNjRfYnl0ZXNfMzZcMDMwJCBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIkZpeGVkNjRCeXRlczM2RW50cnlcMDIyblxuXDAzM2ZpZWxkX21hcF9maXhlZDY0IiArCiAgICAgICJfZG91YmxlXzM3XDAzMCUgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NERvIiArCiAgICAgICJ1YmxlMzdFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCIgKwogICAgICAiXDAzMCYgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lcyIgKwogICAgICAic2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5XDAyMiIgKwogICAgICAicFxuXDAzNGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzlcMDMwXCcgXDAwMyhcMDEzMkouIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNIiArCiAgICAgICJhcHMuRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlcMDIycFxuXDAzNGZpZSIgKwogICAgICAibGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MFwwMzAoIFwwMDMoXDAxMzJKLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXAiICsKICAgICAgIl9maXhlZDY0X2Zsb2F0XzQxXDAzMCkgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRmkiICsKICAgICAgInhlZDY0RmxvYXQ0MUVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9pIiArCiAgICAgICJudDMyXzQyXDAzMCogXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEludDMyIiArCiAgICAgICI0MkVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80M1wwMzArICIgKwogICAgICAiXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZyIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeVwwMjJwXG4iICsKICAgICAgIlwwMzRmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0XDAzMCwgXDAwMyhcMDEzMkoucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW50cnlcMDIyclxuXDAzNWZpZWxkIiArCiAgICAgICJfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDVcMDMwLSBcMDAzKFwwMTMySy5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlcMDIyclxuXDAzNWZpZWxkX21hcCIgKwogICAgICAiX2ZpeGVkNjRfc2ZpeGVkNjRfNDZcMDMwLiBcMDAzKFwwMTMySy5wcm90b2J1Zi5leCIgKwogICAgICAicGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYSIgKwogICAgICAicEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlcMDIyblxuXDAzM2ZpZWxkX21hcF9maXgiICsKICAgICAgImVkNjRfc2ludDMyXzQ3XDAzMC8gXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWUiICsKICAgICAgIm50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQiICsKICAgICAgIjY0U2ludDMyNDdFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX2ZpeGVkNjRfc2luIiArCiAgICAgICJ0NjRfNDhcMDMwMCBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDY0U2ludDY0IiArCiAgICAgICI0OEVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDlcMDMwMSIgKwogICAgICAiIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYSIgKwogICAgICAiZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5XDAyMiIgKwogICAgICAiblxuXDAzM2ZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MFwwMzAyIFwwMDMoXDAxMzJJLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlcMDIyblxuXDAzM2ZpZWxkIiArCiAgICAgICJfbWFwX2ZpeGVkNjRfdWludDY0XzUxXDAzMDMgXDAwMyhcMDEzMkkucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBGaXhlZDY0VWludDY0NTFFbnRyeVwwMjJmXG5cMDI3ZmllbGRfbWFwX2ludCIgKwogICAgICAiMzJfYm9vbF81MlwwMzA0IFwwMDMoXDAxMzJFLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyQm9vbCIgKwogICAgICAiNTJFbnRyeVwwMjJoXG5cMDMwZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzXDAzMDUgXDAwMygiICsKICAgICAgIlwwMTMyRi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBJbnQzMkJ5dGVzNTNFbnRyeVwwMjJqXG5cMDMxZmllIiArCiAgICAgICJsZF9tYXBfaW50MzJfZG91YmxlXzU0XDAzMDYgXDAwMyhcMDEzMkcucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBJbnQzMkRvdWJsZTU0RW50cnlcMDIyZlxuXDAyN2ZpZWxkX21hcF9pbnQzMiIgKwogICAgICAiX2VudW1fNTVcMDMwNyBcMDAzKFwwMTMyRS5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkVudW01NSIgKwogICAgICAiRW50cnlcMDIybFxuXDAzMmZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2XDAzMDggXDAwMygiICsKICAgICAgIlwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5XDAyMmxcblwwMzJmIiArCiAgICAgICJpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3XDAzMDkgXDAwMyhcMDEzMkgucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBJbnQzMkZpeGVkNjQ1N0VudHJ5XDAyMmhcblwwMzBmaWVsZF9tYXBfaSIgKwogICAgICAibnQzMl9mbG9hdF81OFwwMzA6IFwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cGVyaW1lbiIgKwogICAgICAidGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyRiIgKwogICAgICAibG9hdDU4RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OVwwMzAiICsKICAgICAgIjsgXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3MiICsKICAgICAgImFnZVdpdGhNYXBzLkZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlcMDIyaFxuIiArCiAgICAgICJcMDMwZmllbGRfbWFwX2ludDMyX2ludDY0XzYwXDAzMDwgXDAwMyhcMDEzMkYucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBJbnQzMkludDY0NjBFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX2ludCIgKwogICAgICAiMzJfbWVzc2FnZV82MVwwMzA9IFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbiIgKwogICAgICAidGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyTSIgKwogICAgICAiZXNzYWdlNjFFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX2ludDMyX3NmaXhlZDMiICsKICAgICAgIjJfNjJcMDMwPiBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIiICsKICAgICAgIkVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjNcMDMwPyBcMDAzIiArCiAgICAgICIoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudHJ5XDAyMmpcbiIgKwogICAgICAiXDAzMWZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjRcMDMwQCBcMDAzKFwwMTMyRy5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2kiICsKICAgICAgIm50MzJfc2ludDY0XzY1XDAzMEEgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWUiICsKICAgICAgIm50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50MzIiICsKICAgICAgIlNpbnQ2NDY1RW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9pbnQzMl9zdHJpbmdfIiArCiAgICAgICI2NlwwMzBCIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNIiArCiAgICAgICJlc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyU3RyaW5nNjZFbnRyIiArCiAgICAgICJ5XDAyMmpcblwwMzFmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3XDAzMEMgXDAwMyhcMDEzMkcucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlcMDIyalxuXDAzMWZpZWxkX20iICsKICAgICAgImFwX2ludDMyX3VpbnQ2NF82OFwwMzBEIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEkiICsKICAgICAgIm50MzJVaW50NjQ2OEVudHJ5XDAyMmZcblwwMjdmaWVsZF9tYXBfaW50NjRfYm9vIiArCiAgICAgICJsXzY5XDAzMEUgXDAwMyhcMDEzMkUucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvIiArCiAgICAgICIyTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRCb29sNjlFbnRyIiArCiAgICAgICJ5XDAyMmhcblwwMzBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzBcMDMwRiBcMDAzKFwwMTMyRi5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcCIgKwogICAgICAicy5GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5XDAyMmpcblwwMzFmaWVsZF9tYXAiICsKICAgICAgIl9pbnQ2NF9kb3VibGVfNzFcMDMwRyBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQiICsKICAgICAgIjY0RG91YmxlNzFFbnRyeVwwMjJmXG5cMDI3ZmllbGRfbWFwX2ludDY0X2VudW1fIiArCiAgICAgICI3MlwwMzBIIFwwMDMoXDAxMzJFLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNIiArCiAgICAgICJlc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDY0RW51bTcyRW50cnlcMDIyIiArCiAgICAgICJsXG5cMDMyZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzNcMDMwSSBcMDAzKFwwMTMySC5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcCIgKwogICAgICAicy5GaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlcMDIybFxuXDAzMmZpZWxkX20iICsKICAgICAgImFwX2ludDY0X2ZpeGVkNjRfNzRcMDMwSiBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIkludDY0Rml4ZWQ2NDc0RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9pbnQ2NF9mIiArCiAgICAgICJsb2F0Xzc1XDAzMEsgXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRGbG9hdDc1IiArCiAgICAgICJFbnRyeVwwMjJoXG5cMDMwZmllbGRfbWFwX2ludDY0X2ludDMyXzc2XDAzMEwgXDAwMyhcMDEzMiIgKwogICAgICAiRi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdCIgKwogICAgICAiaE1hcHMuRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeVwwMjJoXG5cMDMwZmllbGQiICsKICAgICAgIl9tYXBfaW50NjRfaW50NjRfNzdcMDMwTSBcMDAzKFwwMTMyRi5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIkludDY0SW50NjQ3N0VudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfaW50NjRfbWVzIiArCiAgICAgICJzYWdlXzc4XDAzME4gXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRNZXNzYWdlIiArCiAgICAgICI3OEVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzlcMDMwTyIgKwogICAgICAiIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYSIgKwogICAgICAiZ2VXaXRoTWFwcy5GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5XDAyMiIgKwogICAgICAiblxuXDAzM2ZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MFwwMzBQIFwwMDMoXDAxMzJJLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlcMDIyalxuXDAzMWZpZWxkIiArCiAgICAgICJfbWFwX2ludDY0X3NpbnQzMl84MVwwMzBRIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwSW50NjRTaW50MzI4MUVudHJ5XDAyMmpcblwwMzFmaWVsZF9tYXBfaW50NjRfcyIgKwogICAgICAiaW50NjRfODJcMDMwUiBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NFNpbnQ2NCIgKwogICAgICAiODJFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ludDY0X3N0cmluZ184M1wwMzBTIFwwMDMiICsKICAgICAgIihcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5XDAyMmpcblwwMzFmIiArCiAgICAgICJpZWxkX21hcF9pbnQ2NF91aW50MzJfODRcMDMwVCBcMDAzKFwwMTMyRy5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcEludDY0VWludDMyODRFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ludCIgKwogICAgICAiNjRfdWludDY0Xzg1XDAzMFUgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRVaSIgKwogICAgICAibnQ2NDg1RW50cnlcMDIybFxuXDAzMmZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzgiICsKICAgICAgIjZcMDMwViBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWUiICsKICAgICAgInNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHIiICsKICAgICAgInlcMDIyblxuXDAzM2ZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184N1wwMzBXIFwwMDMoXDAxMzJJIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlcMDIycFxuXDAzNGZpZSIgKwogICAgICAibGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OFwwMzBYIFwwMDMoXDAxMzJKLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwU2ZpeGVkMzJEb3VibGU4OEVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXAiICsKICAgICAgIl9zZml4ZWQzMl9lbnVtXzg5XDAzMFkgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2YiICsKICAgICAgIml4ZWQzMkVudW04OUVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkMzJfIiArCiAgICAgICJmaXhlZDMyXzkwXDAzMFogXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJGIiArCiAgICAgICJpeGVkMzI5MEVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZSIgKwogICAgICAiZDY0XzkxXDAzMFsgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJGaXhlZCIgKwogICAgICAiNjQ5MUVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIiICsKICAgICAgIlwwMzBcXCBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJFbnRyIiArCiAgICAgICJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTNcMDMwXSBcMDAzKFwwMTMySSIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aCIgKwogICAgICAiTWFwcy5GaWVsZE1hcFNmaXhlZDMySW50MzI5M0VudHJ5XDAyMm5cblwwMzNmaWUiICsKICAgICAgImxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NFwwMzBeIFwwMDMoXDAxMzJJLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlcMDIyclxuXDAzNWZpZWxkX21hcF9zIiArCiAgICAgICJmaXhlZDMyX21lc3NhZ2VfOTVcMDMwXyBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTIiArCiAgICAgICJmaXhlZDMyTWVzc2FnZTk1RW50cnlcMDIydFxuXDAzNmZpZWxkX21hcF9zZml4ZSIgKwogICAgICAiZDMyX3NmaXhlZDMyXzk2XDAzMGAgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbSIgKwogICAgICAiZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeCIgKwogICAgICAiZWQzMlNmaXhlZDMyOTZFbnRyeVwwMjJ0XG5cMDM2ZmllbGRfbWFwX3NmaXhlZDMiICsKICAgICAgIjJfc2ZpeGVkNjRfOTdcMDMwYSBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQiICsKICAgICAgIjMyU2ZpeGVkNjQ5N0VudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ZpeGVkMzJfIiArCiAgICAgICJzaW50MzJfOThcMDMwYiBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMlNpIiArCiAgICAgICJudDMyOThFbnRyeVwwMjJwXG5cMDM0ZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NCIgKwogICAgICAiXzk5XDAzMGMgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMiIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSIgKwogICAgICAiRW50cnlcMDIyclxuXDAzNWZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwXDAzMGQiICsKICAgICAgIiBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2EiICsKICAgICAgImdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHIiICsKICAgICAgInlcMDIyclxuXDAzNWZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxXDAzMGUgXDAwMyhcMDEzIiArCiAgICAgICIySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5XDAyMnJcbiIgKwogICAgICAiXDAzNWZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyXDAzMGYgXDAwMyhcMDEzMksucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkVudHJ5XDAyMm5cblwwMzNmaWUiICsKICAgICAgImxkX21hcF9zZml4ZWQ2NF9ib29sXzEwM1wwMzBnIFwwMDMoXDAxMzJJLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwU2ZpeGVkNjRCb29sMTAzRW50cnlcMDIycFxuXDAzNGZpZWxkX21hcF9zIiArCiAgICAgICJmaXhlZDY0X2J5dGVzXzEwNFwwMzBoIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmIiArCiAgICAgICJpeGVkNjRCeXRlczEwNEVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkNiIgKwogICAgICAiNF9kb3VibGVfMTA1XDAzMGkgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNiIgKwogICAgICAiNERvdWJsZTEwNUVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfc2ZpeGVkNjRfZW4iICsKICAgICAgInVtXzEwNlwwMzBqIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm8iICsKICAgICAgInRvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0RW51bTEiICsKICAgICAgIjA2RW50cnlcMDIydFxuXDAzNmZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwIiArCiAgICAgICI3XDAzMGsgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lIiArCiAgICAgICJzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3IiArCiAgICAgICJFbnRyeVwwMjJ0XG5cMDM2ZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4XDAzMCIgKwogICAgICAibCBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzcyIgKwogICAgICAiYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbiIgKwogICAgICAidHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5XDAzMG0gXDAwMygiICsKICAgICAgIlwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlcMDIycFxuIiArCiAgICAgICJcMDM0ZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMFwwMzBuIFwwMDMoXDAxMzJKLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5XDAyMnBcblwwMzRmaWVsZCIsCiAgICAgICJfbWFwX3NmaXhlZDY0X2ludDY0XzExMVwwMzBvIFwwMDMoXDAxMzJKLnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwU2ZpeGVkNjRJbnQ2NDExMUVudHJ5XDAyMnRcblwwMzZmaWVsZF9tYXBfcyIgKwogICAgICAiZml4ZWQ2NF9tZXNzYWdlXzExMlwwMzBwIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlcMDIydlxuXDAzN2ZpZWxkX21hcF9zZmkiICsKICAgICAgInhlZDY0X3NmaXhlZDMyXzExM1wwMzBxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFMiICsKICAgICAgImZpeGVkNjRTZml4ZWQzMjExM0VudHJ5XDAyMnZcblwwMzdmaWVsZF9tYXBfc2ZpIiArCiAgICAgICJ4ZWQ2NF9zZml4ZWQ2NF8xMTRcMDMwciBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTIiArCiAgICAgICJmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaSIgKwogICAgICAieGVkNjRfc2ludDMyXzExNVwwMzBzIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaSIgKwogICAgICAibWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaSIgKwogICAgICAieGVkNjRTaW50MzIxMTVFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlZDYiICsKICAgICAgIjRfc2ludDY0XzExNlwwMzB0IFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDYiICsKICAgICAgIjRTaW50NjQxMTZFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlZDY0X3N0IiArCiAgICAgICJyaW5nXzExN1wwMzB1IFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QIiArCiAgICAgICJyb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0U3RyIiArCiAgICAgICJpbmcxMTdFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMiIgKwogICAgICAiXzExOFwwMzB2IFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90byIgKwogICAgICAiMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0VWludDMyMSIgKwogICAgICAiMThFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkiICsKICAgICAgIlwwMzB3IFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXMiICsKICAgICAgInNhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW4iICsKICAgICAgInRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMFwwMzB4IFwwMDMoXDAxMzJHIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5XDAyMmxcblwwMzJmaWVsZCIgKwogICAgICAiX21hcF9zaW50MzJfYnl0ZXNfMTIxXDAzMHkgXDAwMyhcMDEzMkgucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBTaW50MzJCeXRlczEyMUVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfc2ludDMiICsKICAgICAgIjJfZG91YmxlXzEyMlwwMzB6IFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMkQiICsKICAgICAgIm91YmxlMTIyRW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9zaW50MzJfZW51bV8xIiArCiAgICAgICIyM1wwMzB7IFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNIiArCiAgICAgICJlc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyIiArCiAgICAgICJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0XDAzMHwgXDAwMyhcMDEzMiIgKwogICAgICAiSi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdCIgKwogICAgICAiaE1hcHMuRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlcMDIycFxuXDAzNGYiICsKICAgICAgImllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNVwwMzB9IFwwMDMoXDAxMzJKLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5XDAyMmxcblwwMzJmaWVsZF9tIiArCiAgICAgICJhcF9zaW50MzJfZmxvYXRfMTI2XDAzMH4gXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwIiArCiAgICAgICJTaW50MzJGbG9hdDEyNkVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfc2ludDMyXyIgKwogICAgICAiaW50MzJfMTI3XDAzMFwxNzcgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDMySW50MyIgKwogICAgICAiMjEyN0VudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOFwwMzAiICsKICAgICAgIlwyMDBcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXMiICsKICAgICAgInNhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnkiICsKICAgICAgIlwwMjJxXG5cMDM0ZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOVwwMzBcMjAxXDAwMSBcMDAzKFwwMTMyIiArCiAgICAgICJKLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0IiArCiAgICAgICJoTWFwcy5GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeVwwMjJzXG5cMDM1ZiIgKwogICAgICAiaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMFwwMzBcMjAyXDAwMSBcMDAzKFwwMTMySy5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcCIgKwogICAgICAicy5GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlcMDIyc1xuXDAzNWZpZWwiICsKICAgICAgImRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzFcMDMwXDIwM1wwMDEgXDAwMyhcMDEzMksucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUVudHJ5XDAyMm9cblwwMzNmaWVsZF9tIiArCiAgICAgICJhcF9zaW50MzJfc2ludDMyXzEzMlwwMzBcMjA0XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcFNpbnQzMlNpbnQzMjEzMkVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc2ludCIgKwogICAgICAiMzJfc2ludDY0XzEzM1wwMzBcMjA1XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZSIgKwogICAgICAibnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50MyIgKwogICAgICAiMlNpbnQ2NDEzM0VudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc2ludDMyX3N0cmkiICsKICAgICAgIm5nXzEzNFwwMzBcMjA2XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHIiICsKICAgICAgIm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJTdHJpbmciICsKICAgICAgIjEzNEVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzVcMDMwIiArCiAgICAgICJcMjA3XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyIiArCiAgICAgICJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzZcMDMwXDIxMFwwMDEgXDAwMyhcMDEzMiIgKwogICAgICAiSS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdCIgKwogICAgICAiaE1hcHMuRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeVwwMjJrXG5cMDMxZmkiICsKICAgICAgImVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3XDAzMFwyMTFcMDAxIFwwMDMoXDAxMzJHLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfc2luIiArCiAgICAgICJ0NjRfYnl0ZXNfMTM4XDAzMFwyMTJcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2IiArCiAgICAgICI0Qnl0ZXMxMzhFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF9kb3VibCIgKwogICAgICAiZV8xMzlcMDMwXDIxM1wwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0RG91YmxlMSIgKwogICAgICAiMzlFbnRyeVwwMjJrXG5cMDMxZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MFwwMzBcMjE0XDAwMSAiICsKICAgICAgIlwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeVwwMjJxXG5cMDM0IiArCiAgICAgICJmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxXDAzMFwyMTVcMDAxIFwwMDMoXDAxMzJKLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5XDAyMnFcblwwMzRmaWVsZCIgKwogICAgICAiX21hcF9zaW50NjRfZml4ZWQ2NF8xNDJcMDMwXDIxNlwwMDEgXDAwMyhcMDEzMkoucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZSIgKwogICAgICAibGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF8iICsKICAgICAgInNpbnQ2NF9mbG9hdF8xNDNcMDMwXDIxN1wwMDEgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2kiICsKICAgICAgIm50NjRGbG9hdDE0M0VudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfc2ludDY0X2luIiArCiAgICAgICJ0MzJfMTQ0XDAzMFwyMjBcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QIiArCiAgICAgICJyb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEludDMyIiArCiAgICAgICIxNDRFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDVcMDMwXDIyMSIgKwogICAgICAiXDAwMSBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzcyIgKwogICAgICAiYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRJbnQ2NDE0NUVudHJ5XDAyMiIgKwogICAgICAicVxuXDAzNGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDZcMDMwXDIyMlwwMDEgXDAwMyhcMDEzMkoiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlcMDIyc1xuXDAzNWZpIiArCiAgICAgICJlbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDdcMDMwXDIyM1wwMDEgXDAwMyhcMDEzMksucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzIiArCiAgICAgICIuRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0VudHJ5XDAyMnNcblwwMzVmaWVsZCIgKwogICAgICAiX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4XDAzMFwyMjRcMDAxIFwwMDMoXDAxMzJLLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWEiICsKICAgICAgInBfc2ludDY0X3NpbnQzMl8xNDlcMDMwXDIyNVwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBTaW50NjRTaW50MzIxNDlFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQ2IiArCiAgICAgICI0X3NpbnQ2NF8xNTBcMDMwXDIyNlwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0IiArCiAgICAgICJTaW50NjQxNTBFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF9zdHJpbiIgKwogICAgICAiZ18xNTFcMDMwXDIyN1wwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0U3RyaW5nMSIgKwogICAgICAiNTFFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyXDAzMFwyMzAiICsKICAgICAgIlwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3MiICsKICAgICAgImFnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0VWludDMyMTUyRW50cnkiICsKICAgICAgIlwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzXDAzMFwyMzFcMDAxIFwwMDMoXDAxMzJJIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwU2ludDY0VWludDY0MTUzRW50cnlcMDIya1xuXDAzMWZpZSIgKwogICAgICAibGRfbWFwX3N0cmluZ19ib29sXzE1NFwwMzBcMjMyXDAwMSBcMDAzKFwwMTMyRy5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbCIgKwogICAgICAiZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3N0cmkiICsKICAgICAgIm5nX2J5dGVzXzE1NVwwMzBcMjMzXDAwMSBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmciICsKICAgICAgIkJ5dGVzMTU1RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zdHJpbmdfZG91YmxlIiArCiAgICAgICJfMTU2XDAzMFwyMzRcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90IiArCiAgICAgICJvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ0RvdWJsZTE1IiArCiAgICAgICI2RW50cnlcMDIya1xuXDAzMWZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTdcMDMwXDIzNVwwMDEgXDAwMyIgKwogICAgICAiKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSIgKwogICAgICAiV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlcMDIycVxuXDAzNGYiICsKICAgICAgImllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OFwwMzBcMjM2XDAwMSBcMDAzKFwwMTMySi5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMiICsKICAgICAgIi5GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeVwwMjJxXG5cMDM0ZmllbGRfIiArCiAgICAgICJtYXBfc3RyaW5nX2ZpeGVkNjRfMTU5XDAzMFwyMzdcMDAxIFwwMDMoXDAxMzJKLnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfcyIgKwogICAgICAidHJpbmdfZmxvYXRfMTYwXDAzMFwyNDBcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaSIgKwogICAgICAibWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFN0ciIgKwogICAgICAiaW5nRmxvYXQxNjBFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3N0cmluZ19pbnQiICsKICAgICAgIjMyXzE2MVwwMzBcMjQxXDAwMSBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHIiICsKICAgICAgIm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdJbnQzMjEiICsKICAgICAgIjYxRW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyXDAzMFwyNDJcMDAxIiArCiAgICAgICIgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhIiArCiAgICAgICJnZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeVwwMjJxIiArCiAgICAgICJcblwwMzRmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzXDAzMFwyNDNcMDAxIFwwMDMoXDAxMzJKLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTSIgKwogICAgICAiYXBzLkZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0VudHJ5XDAyMnNcblwwMzVmaWUiICsKICAgICAgImxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0XDAzMFwyNDRcMDAxIFwwMDMoXDAxMzJLLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeVwwMjJzXG5cMDM1ZmllbGRfIiArCiAgICAgICJtYXBfc3RyaW5nX3NmaXhlZDY0XzE2NVwwMzBcMjQ1XDAwMSBcMDAzKFwwMTMySy5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcCIgKwogICAgICAiX3N0cmluZ19zaW50MzJfMTY2XDAzMFwyNDZcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiU3RyaW5nU2ludDMyMTY2RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zdHJpbmciICsKICAgICAgIl9zaW50NjRfMTY3XDAzMFwyNDdcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ1MiICsKICAgICAgImludDY0MTY3RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zdHJpbmdfc3RyaW5nIiArCiAgICAgICJfMTY4XDAzMFwyNTBcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90IiArCiAgICAgICJvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ1N0cmluZzE2IiArCiAgICAgICI4RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OVwwMzBcMjUxXDAwMSIgKwogICAgICAiIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYSIgKwogICAgICAiZ2VXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5XDAyMiIgKwogICAgICAib1xuXDAzM2ZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MFwwMzBcMjUyXDAwMSBcMDAzKFwwMTMySS4iICsKICAgICAgInByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE0iICsKICAgICAgImFwcy5GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5XDAyMmtcblwwMzFmaWVsIiArCiAgICAgICJkX21hcF91aW50MzJfYm9vbF8xNzFcMDMwXDI1M1wwMDEgXDAwMyhcMDEzMkcucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBVaW50MzJCb29sMTcxRW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF91aW50MyIgKwogICAgICAiMl9ieXRlc18xNzJcMDMwXDI1NFwwMDEgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyQiIgKwogICAgICAieXRlczE3MkVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8iICsKICAgICAgIjE3M1wwMzBcMjU1XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50MzJEb3VibGUxNzMiICsKICAgICAgIkVudHJ5XDAyMmtcblwwMzFmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0XDAzMFwyNTZcMDAxIFwwMDMoIiArCiAgICAgICJcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXIiArCiAgICAgICJpdGhNYXBzLkZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5XDAyMnFcblwwMzRmaSIgKwogICAgICAiZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzVcMDMwXDI1N1wwMDEgXDAwMyhcMDEzMkoucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLiIgKwogICAgICAiRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlcMDIycVxuXDAzNGZpZWxkX20iICsKICAgICAgImFwX3VpbnQzMl9maXhlZDY0XzE3NlwwMzBcMjYwXDAwMSBcMDAzKFwwMTMySi5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGQiICsKICAgICAgIk1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3VpIiArCiAgICAgICJudDMyX2Zsb2F0XzE3N1wwMzBcMjYxXDAwMSBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50IiArCiAgICAgICIzMkZsb2F0MTc3RW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF91aW50MzJfaW50MyIgKwogICAgICAiMl8xNzhcMDMwXDI2MlwwMDEgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMySW50MzIxNyIgKwogICAgICAiOEVudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OVwwMzBcMjYzXDAwMSAiICsKICAgICAgIlwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlcMDIycVxuIiArCiAgICAgICJcMDM0ZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MFwwMzBcMjY0XDAwMSBcMDAzKFwwMTMySi5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeVwwMjJzXG5cMDM1ZmllbCIgKwogICAgICAiZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MVwwMzBcMjY1XDAwMSBcMDAzKFwwMTMySy5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlcMDIyc1xuXDAzNWZpZWxkX20iICsKICAgICAgImFwX3VpbnQzMl9zZml4ZWQ2NF8xODJcMDMwXDI2NlwwMDEgXDAwMyhcMDEzMksucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWwiICsKICAgICAgImRNYXBVaW50MzJTZml4ZWQ2NDE4MkVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfIiArCiAgICAgICJ1aW50MzJfc2ludDMyXzE4M1wwMzBcMjY3XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVIiArCiAgICAgICJpbnQzMlNpbnQzMjE4M0VudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfdWludDMyXyIgKwogICAgICAic2ludDY0XzE4NFwwMzBcMjcwXDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YSIgKwogICAgICAibC5Qcm90bzJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50MzJTaSIgKwogICAgICAibnQ2NDE4NEVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfdWludDMyX3N0cmluZ18iICsKICAgICAgIjE4NVwwMzBcMjcxXDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50MzJTdHJpbmcxODUiICsKICAgICAgIkVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODZcMDMwXDI3MlwwMDEgIiArCiAgICAgICJcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnIiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeVwwMjJvIiArCiAgICAgICJcblwwMzNmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODdcMDMwXDI3M1wwMDEgXDAwMyhcMDEzMkkucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeVwwMjJrXG5cMDMxZmllbGQiICsKICAgICAgIl9tYXBfdWludDY0X2Jvb2xfMTg4XDAzMFwyNzRcMDAxIFwwMDMoXDAxMzJHLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE0iICsKICAgICAgImFwVWludDY0Qm9vbDE4OEVudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfdWludDY0IiArCiAgICAgICJfYnl0ZXNfMTg5XDAzMFwyNzVcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhIiArCiAgICAgICJsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NEJ5IiArCiAgICAgICJ0ZXMxODlFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMSIgKwogICAgICAiOTBcMDMwXDI3NlwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMiIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0RG91YmxlMTkwRSIgKwogICAgICAibnRyeVwwMjJrXG5cMDMxZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MVwwMzBcMjc3XDAwMSBcMDAzKFwwMTMiICsKICAgICAgIjJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeVwwMjJxXG5cMDM0ZmllIiArCiAgICAgICJsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyXDAzMFwzMDBcMDAxIFwwMDMoXDAxMzJKLnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GIiArCiAgICAgICJpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkVudHJ5XDAyMnFcblwwMzRmaWVsZF9tYSIgKwogICAgICAicF91aW50NjRfZml4ZWQ2NF8xOTNcMDMwXDMwMVwwMDEgXDAwMyhcMDEzMkoucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBVaW50NjRGaXhlZDY0MTkzRW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF91aW4iICsKICAgICAgInQ2NF9mbG9hdF8xOTRcMDMwXDMwMlwwMDEgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWUiICsKICAgICAgIm50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDYiICsKICAgICAgIjRGbG9hdDE5NEVudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfdWludDY0X2ludDMyIiArCiAgICAgICJfMTk1XDAzMFwzMDNcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90IiArCiAgICAgICJvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NEludDMyMTk1IiArCiAgICAgICJFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTZcMDMwXDMwNFwwMDEgXDAwMyIgKwogICAgICAiKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSIgKwogICAgICAiV2l0aE1hcHMuRmllbGRNYXBVaW50NjRJbnQ2NDE5NkVudHJ5XDAyMnFcblwwMzQiICsKICAgICAgImZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTdcMDMwXDMwNVwwMDEgXDAwMyhcMDEzMkoucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlcMDIyc1xuXDAzNWZpZWxkIiArCiAgICAgICJfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOThcMDMwXDMwNlwwMDEgXDAwMyhcMDEzMksucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5XDAyMnNcblwwMzVmaWVsZF9tYSIgKwogICAgICAicF91aW50NjRfc2ZpeGVkNjRfMTk5XDAzMFwzMDdcMDAxIFwwMDMoXDAxMzJLLnByb3RvYnVmLiIgKwogICAgICAiZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwcy5GaWVsZCIgKwogICAgICAiTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3UiICsKICAgICAgImludDY0X3NpbnQzMl8yMDBcMDMwXDMxMFwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWkiICsKICAgICAgIm50NjRTaW50MzIyMDBFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9zIiArCiAgICAgICJpbnQ2NF8yMDFcMDMwXDMxMVwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8yTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0U2luIiArCiAgICAgICJ0NjQyMDFFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMiIgKwogICAgICAiMDJcMDMwXDMxMlwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMiIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0U3RyaW5nMjAyRSIgKwogICAgICAibnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzXDAzMFwzMTNcMDAxIFwwMDMiICsKICAgICAgIihcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2UiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwVWludDY0VWludDMyMjAzRW50cnlcMDIyb1xuIiArCiAgICAgICJcMDMzZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0XDAzMFwzMTRcMDAxIFwwMDMoXDAxMzJJLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwVWludDY0VWludDY0MjA0RW50cnlcMDMyOFxuXDAyNkZpZWxkTSIgKwogICAgICAiYXBCb29sQm9vbDFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI6XG5cMDMwRmllbGRNYXBCIiArCiAgICAgICJvb2xEb3VibGUzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgIiArCiAgICAgICJcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmdcblwwMjZGaWVsZE1hcEJvb2xFbnVtNEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAxMFwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyLS5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbCIgKwogICAgICAiZE1hcEJvb2xGaXhlZDMyNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBCb29sRml4ZWQ2NDZFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpIiArCiAgICAgICJlbGRNYXBCb29sRmxvYXQ3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhIiArCiAgICAgICJsdWVcMDMwXDAwMiBcMDAxKFwwMDI6XDAwMjhcMDAxXDAzMjlcblwwMjdGaWVsZE1hcEJvb2xJbnQzMjhFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWwiICsKICAgICAgImRNYXBCb29sSW50NjQ5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmJcblwwMzJGaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyM1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMiQucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkIiArCiAgICAgICJNYXBCb29sU2ZpeGVkMzIxMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBCb29sU2ZpeGVkNjQxMiIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI7XG4iICsKICAgICAgIlwwMzFGaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyIiArCiAgICAgICJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBCb29sU2ludDY0IiArCiAgICAgICIxNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI7XG5cMDMxRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xVaW50IiArCiAgICAgICIzMjE2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOCIgKwogICAgICAiXDAwMVwwMzI7XG5cMDMxRmllbGRNYXBCb29sVWludDY0MTdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwRml4ZWQzIiArCiAgICAgICIyQm9vbDE4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkMzJCeXRlczE5RW50cnlcMDIyXDAxM1xuXDAwM2siICsKICAgICAgImV5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEYiICsKICAgICAgIml4ZWQzMkRvdWJsZTIwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmtcblwwMzJGaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI/XG5cMDM1RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcEZpeCIgKwogICAgICAiZWQzMkZpeGVkNjQyM0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllIiArCiAgICAgICJsZE1hcEZpeGVkMzJJbnQzMjI1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkMzJJbnQ2NCIgKwogICAgICAiMjZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMiIgKwogICAgICAiZVxuXDAzNUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAwN1wwMjIzXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZSIgKwogICAgICAibnRhbC5Qcm90bzJNZXNzYWdlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBGaXhlZDMiICsKICAgICAgIjJTZml4ZWQzMjI4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIiICsKICAgICAgIiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaSIgKwogICAgICAiZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMzJTaW4iICsKICAgICAgInQ2NDMxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRmkiICsKICAgICAgInhlZDMyVWludDMyMzNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmkiICsKICAgICAgImVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzIiArCiAgICAgICIzNkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI+XG5cMDM0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMya1xuXDAzMkZpZWxkTWFwRml4ZWQiICsKICAgICAgIjY0RW51bTM4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKCIgKwogICAgICAiXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLiIgKwogICAgICAiVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkiICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuIiArCiAgICAgICJcMDM1RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxICIgKwogICAgICAiXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkNiIgKwogICAgICAiNEZsb2F0NDFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKCIgKwogICAgICAiXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwIiArCiAgICAgICJGaXhlZDY0SW50NjQ0M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJlXG5cMDM1RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2U6XDAwMjhcMDAxXDAzMkBcblwwMzZGaSIgKwogICAgICAiZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwRml4ZWQ2NFMiICsKICAgICAgImZpeGVkNjQ0NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTSIgKwogICAgICAiYXBGaXhlZDY0U2ludDY0NDhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQiICsKICAgICAgIjlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI+IiArCiAgICAgICJcblwwMzRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRml4ZWQ2IiArCiAgICAgICI0VWludDY0NTFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAwNDpcMDAyOFwwMDFcMDMyOlxuXDAzMEZpZWxkTWFwSW50MzJCb29sNTJFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW4iICsKICAgICAgInQzMkJ5dGVzNTNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJpXG5cMDMwRmllbGRNYSIgKwogICAgICAicEludDMyRW51bTU1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI8XG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzIiArCiAgICAgICJhZ2UuVGVzdEVudW06XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludDMyRml4ZWQzMiIgKwogICAgICAiNTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMiIgKwogICAgICAiPVxuXDAzM0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50MzJGIiArCiAgICAgICJsb2F0NThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDMiICsKICAgICAgIjJJbnQ2NDYwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSgiICsKICAgICAgIlwwMDM6XDAwMjhcMDAxXDAzMmNcblwwMzNGaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLlByb3RvMk1lc3NhZ2U6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEluIiArCiAgICAgICJ0MzJTZml4ZWQzMjYyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmkiICsKICAgICAgImVsZE1hcEludDMyU2ludDMyNjRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJTaW50NjQ2IiArCiAgICAgICI1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI8IiArCiAgICAgICJcblwwMzJGaWVsZE1hcEludDMyU3RyaW5nNjZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDMyVWluIiArCiAgICAgICJ0MzI2N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI6XG5cMDMwRmllbGRNYXBJbnQ2IiArCiAgICAgICI0Qm9vbDY5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQiICsKICAgICAgIjY0RG91YmxlNzFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyaVxuXDAzMEZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpIiArCiAgICAgICJlbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHIiICsKICAgICAgIlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBJbnQ2NEZpeGVkNiIgKwogICAgICAiNDc0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMSIgKwogICAgICAiXDAzMjtcblwwMzFGaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxIiArCiAgICAgICIoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJbnQ2NEluIiArCiAgICAgICJ0MzI3NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyY1xuXDAzM0ZpZWxkTWFwSW50NjQiICsKICAgICAgIk1lc3NhZ2U3OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyM1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwIiwKICAgICAgIkludDY0U2ZpeGVkNjQ4MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMjxcblwwMzJGaSIgKwogICAgICAiZWxkTWFwSW50NjRTaW50NjQ4MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQ2NFN0cmluZzgiICsKICAgICAgIjNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI8IiArCiAgICAgICJcblwwMzJGaWVsZE1hcEludDY0VWludDMyODRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDY0VWluIiArCiAgICAgICJ0NjQ4NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZmkiICsKICAgICAgInhlZDMyQnl0ZXM4N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmxcblwwMzNGaSIgKwogICAgICAiZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMjwiICsKICAgICAgIlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8yTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeCIgKwogICAgICAiZWQzMkZpeGVkMzI5MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI+XG5cMDM0IiArCiAgICAgICJGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZWQzMiIgKwogICAgICAiSW50MzI5M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyZlxuXDAzNkZpZWxkTWFwIiArCiAgICAgICJTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyM1xuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjJNZXNzYWdlOlwwMDI4XDAwMVwwMzJBXG5cMDM3RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyIiArCiAgICAgICI5NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyIiArCiAgICAgICJBXG5cMDM3RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU2YiICsKICAgICAgIml4ZWQzMlNpbnQzMjk4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyQFxuXDAzNiIgKwogICAgICAiRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkIiArCiAgICAgICIzMlVpbnQzMjEwMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShccjpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpIiArCiAgICAgICJlbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU2ZpeGVkNjRCeSIgKwogICAgICAidGVzMTA0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OiIgKwogICAgICAiXDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMm1cblwwMzRGaWVsZE1hIiArCiAgICAgICJwU2ZpeGVkNjRFbnVtMTA2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjI8XG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzIiICsKICAgICAgIk1lc3NhZ2UuVGVzdEVudW06XDAwMjhcMDAxXDAzMkFcblwwMzdGaWVsZE1hcFNmaXhlZDY0IiArCiAgICAgICJGaXhlZDMyMTA3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgIiArCiAgICAgICJcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMkFcblwwMzdGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI/XG5cMDM1RmkiICsKICAgICAgImVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwIiArCiAgICAgICJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU2ZpeGVkNjRJIiArCiAgICAgICJudDMyMTEwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1IiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyZ1xuXDAzN0ZpZWxkTWEiICsKICAgICAgInBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMjNcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMiQucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8yTWVzc2FnZTpcMDAyOFwwMDFcMDMyQlxuIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQiICsKICAgICAgIjMyMTEzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMkJcbiBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTSIgKwogICAgICAiYXBTZml4ZWQ2NFNpbnQzMjExNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQ2NFNpbnQiICsKICAgICAgIjY0MTE2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDIiICsKICAgICAgIjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXAiICsKICAgICAgIlNmaXhlZDY0VWludDMyMTE4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NCIgKwogICAgICAiMTE5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMSIgKwogICAgICAiXDAzMjxcblwwMzJGaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDMyIiArCiAgICAgICJCeXRlczEyMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoIiArCiAgICAgICJcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMya1xuXDAzMkZpZWxkTWEiICsKICAgICAgInBTaW50MzJFbnVtMTIzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjI8XG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZSIgKwogICAgICAic3NhZ2UuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNpbnQzMkZpeGUiICsKICAgICAgImQzMjEyNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzoiICsKICAgICAgIlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcCIgKwogICAgICAiU2ludDMyRmxvYXQxMjZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpIiArCiAgICAgICJlbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHIiICsKICAgICAgIlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJlXG5cMDM1RmllbGRNYXBTaW50MzJNZXNzYSIgKwogICAgICAiZ2UxMjlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2U6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyQFxuXDAzNkZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2kiICsKICAgICAgIm50MzJTZml4ZWQ2NDEzMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50MzJTaW50MzIxMzJFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNCIgKwogICAgICAiRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDMyU3QiICsKICAgICAgInJpbmcxMzRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0IiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwIiArCiAgICAgICJTaW50MzJVaW50NjQxMzZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmkiICsKICAgICAgImVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcciIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQ2NERvdWJsIiArCiAgICAgICJlMTM5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4IiArCiAgICAgICJcMDAxXDAzMmtcblwwMzJGaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMjJcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTSIgKwogICAgICAiYXBTaW50NjRGaXhlZDMyMTQxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNSIgKwogICAgICAidmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQiICsKICAgICAgIjE0MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI9XG5cMDMzRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTaW50NiIgKwogICAgICAiNEludDMyMTQ0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmVcblwwMzVGaWVsZE1hIiArCiAgICAgICJwU2ludDY0TWVzc2FnZTE0NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyM1xuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjJNZXNzYWdlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0IiArCiAgICAgICI3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAIiArCiAgICAgICJcblwwMzZGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQiICsKICAgICAgIjY0U2ludDMyMTQ5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIiICsKICAgICAgIiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbCIgKwogICAgICAiZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDY0VWludDMyIiArCiAgICAgICIxNTJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMSIgKwogICAgICAiXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBTdHJpIiArCiAgICAgICJuZ0Jvb2wxNTRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMTA6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYSIgKwogICAgICAicFN0cmluZ0RvdWJsZTE1NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMya1xuXDAzMkZpZWxkTWFwU3RyaW5nRW51bTE1N0VuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bTpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlcMDIyXDAxM1xuXDAwM2siICsKICAgICAgImV5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTIiArCiAgICAgICJ0cmluZ0ZpeGVkNjQxNTlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRiIgKwogICAgICAiaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyIiArCiAgICAgICJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTdHJpbmdJbnQ2IiArCiAgICAgICI0MTYyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOCIgKwogICAgICAiXDAwMVwwMzJlXG5cMDM1RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcdFwwMjIzXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzJNZXNzYWdlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTdHJpIiArCiAgICAgICJuZ1NmaXhlZDMyMTY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyPlxuXDAzNCIgKwogICAgICAiRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFN0cmluZ1NpIiArCiAgICAgICJudDY0MTY3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMiIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlN0cmluZ1VpbnQzMjE2OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMiIgKwogICAgICAiRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyIiArCiAgICAgICJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50MzJCeXRlIiArCiAgICAgICJzMTcyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOCIgKwogICAgICAiXDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmtcblwwMzJGaWVsZE1hcFVpbiIgKwogICAgICAidDMyRW51bTE3NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMjxcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZyIgKwogICAgICAiZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwVWludDMyRml4ZWQzMjEiICsKICAgICAgIjc1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI/XG5cMDM1RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50IiArCiAgICAgICIzMkZsb2F0MTc3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50MzJJbnQzMjE3OEVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTSIgKwogICAgICAiYXBVaW50MzJJbnQ2NDE3OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyZVxuXDAzNUZpZWxkTWFwVWludDMyTWVzc2FnZTE4IiArCiAgICAgICIwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyM1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMiQucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZTpcMDAyOFwwMDFcMDMyQFxuXDAzNiIgKwogICAgICAiRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwVWludDMyIiArCiAgICAgICJTZml4ZWQ2NDE4MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyU2ludDMyMTgzRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbCIgKwogICAgICAiZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyU3RyaW5nIiArCiAgICAgICIxODVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI+XG5cMDM0RmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50IiArCiAgICAgICIzMlVpbnQ2NDE4N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNIiArCiAgICAgICJhcFVpbnQ2NEJ5dGVzMTg5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhIiArCiAgICAgICJsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJrXG4iICsKICAgICAgIlwwMzJGaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0IiArCiAgICAgICJcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwVWkiICsKICAgICAgIm50NjRGaXhlZDMyMTkyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuXDAzMyIgKwogICAgICAiRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDQiICsKICAgICAgIlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50NjRJbnQiICsKICAgICAgIjMyMTk1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmVcblwwMzVGaWVsZE1hcFVpbiIgKwogICAgICAidDY0TWVzc2FnZTE5N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyM1xuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmkiICsKICAgICAgImVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQ2NFNpIiArCiAgICAgICJudDMyMjAwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlVpbnQ2NFN0cmluZzIwMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDY0VWludDMyMjAzRSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0IiArCiAgICAgICJGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMTpKXG5cMDE2ZmllbGRfZG91YmxlXzFcMDIyMiIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aCIgKwogICAgICAiRXh0ZW5zaW9uc1wwMzBcMDAxIFwwMDEoXDAwMTpJXG5ccmZpZWxkX2Zsb2F0XzJcMDIyMi5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuIiArCiAgICAgICJzaW9uc1wwMzBcMDAyIFwwMDEoXDAwMjpJXG5ccmZpZWxkX2ludDY0XzNcMDIyMi5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnMiICsKICAgICAgIlwwMzBcMDAzIFwwMDEoXDAwMzpKXG5cMDE2ZmllbGRfdWludDY0XzRcMDIyMi5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwXDAwNCBcMDAxIiArCiAgICAgICIoXDAwNDpJXG5ccmZpZWxkX2ludDMyXzVcMDIyMi5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwXDAwNSBcMDAxKFwwMDU6S1xuIiArCiAgICAgICJcMDE3ZmllbGRfZml4ZWQ2NF82XDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zXDAzMFwwMDYgXDAwMShcMDA2OktcblwwMTdmaSIgKwogICAgICAiZWxkX2ZpeGVkMzJfN1wwMjIyLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QciIgKwogICAgICAib3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc1wwMzBcMDA3IFwwMDEoXDAwNzpIXG5cMDE0ZmllbGQiICsKICAgICAgIl9ib29sXzhcMDIyMi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWUiICsKICAgICAgInNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwXDAxMCBcMDAxKFwwMTA6SlxuXDAxNmZpZWxkX3N0cmluIiArCiAgICAgICJnXzlcMDIyMi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnIiArCiAgICAgICJlV2l0aEV4dGVuc2lvbnNcMDMwXHQgXDAwMShcdDpyXG5cMDIwZmllbGRfbWVzc2FnZV8xIiArCiAgICAgICIwXDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXIiArCiAgICAgICJpdGhFeHRlbnNpb25zXDAzMFxuIFwwMDEoXDAxMzIkLnByb3RvYnVmLmV4cGVyaW1lbiIgKwogICAgICAidGFsLlByb3RvMk1lc3NhZ2U6SlxuXDAxNmZpZWxkX2J5dGVzXzExXDAyMjIucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHQiICsKICAgICAgImVuc2lvbnNcMDMwXDAxMyBcMDAxKFwwMTQ6S1xuXDAxN2ZpZWxkX3VpbnQzMl8xMlwwMjIyLnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zIiArCiAgICAgICJpb25zXDAzMFwwMTQgXDAwMShccjp4XG5ccmZpZWxkX2VudW1fMTNcMDIyMi5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwIiArCiAgICAgICJcciBcMDAxKFwwMTYyLS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzcyIgKwogICAgICAiYWdlLlRlc3RFbnVtOk1cblwwMjFmaWVsZF9zZml4ZWQzMl8xNFwwMjIyLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW4iICsKICAgICAgInNpb25zXDAzMFwwMTYgXDAwMShcMDE3Ok1cblwwMjFmaWVsZF9zZml4ZWQ2NF8xNVwwMjIyLnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zIiArCiAgICAgICJpb25zXDAzMFwwMTcgXDAwMShcMDIwOktcblwwMTdmaWVsZF9zaW50MzJfMTZcMDIyMi5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbiIgKwogICAgICAic1wwMzBcMDIwIFwwMDEoXDAyMTpLXG5cMDE3ZmllbGRfc2ludDY0XzE3XDAyMjIucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zXDAzMFwwMjEiICsKICAgICAgIiBcMDAxKFwwMjI6VFxuXDAyNGZpZWxkX2RvdWJsZV9saXN0XzE4XDAyMjIucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zIiArCiAgICAgICJcMDMwXDAyMiBcMDAzKFwwMDFCXDAwMlwwMjBcMDAwOlNcblwwMjNmaWVsZF9mbG9hdF9saXN0XzE5XDAyMjIucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbiIgKwogICAgICAic2lvbnNcMDMwXDAyMyBcMDAzKFwwMDJCXDAwMlwwMjBcMDAwOlNcblwwMjNmaWVsZF9pbnQ2NF9saXN0XzIwXDAyMjIiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGgiICsKICAgICAgIkV4dGVuc2lvbnNcMDMwXDAyNCBcMDAzKFwwMDNCXDAwMlwwMjBcMDAwOlRcblwwMjRmaWVsZF91aW50NjRfbGlzIiArCiAgICAgICJ0XzIxXDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhIiArCiAgICAgICJnZVdpdGhFeHRlbnNpb25zXDAzMFwwMjUgXDAwMyhcMDA0QlwwMDJcMDIwXDAwMDpTXG5cMDIzZmllbGRfaW50MyIgKwogICAgICAiMl9saXN0XzIyXDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMiIgKwogICAgICAiTWVzc2FnZVdpdGhFeHRlbnNpb25zXDAzMFwwMjYgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMDpVXG5cMDI1ZmllbGQiICsKICAgICAgIl9maXhlZDY0X2xpc3RfMjNcMDIyMi5wcm90b2J1Zi5leHBlcmltZW50YWwiICsKICAgICAgIi5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwXDAyNyBcMDAzKFwwMDZCXDAwMlwwMjBcMDAwOlUiICsKICAgICAgIlxuXDAyNWZpZWxkX2ZpeGVkMzJfbGlzdF8yNFwwMjIyLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc1wwMzBcMDMwIFwwMDMoIiArCiAgICAgICJcMDA3QlwwMDJcMDIwXDAwMDpSXG5cMDIyZmllbGRfYm9vbF9saXN0XzI1XDAyMjIucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zXDAzMCIgKwogICAgICAiXDAzMSBcMDAzKFwwMTBCXDAwMlwwMjBcMDAwOlRcblwwMjRmaWVsZF9zdHJpbmdfbGlzdF8yNlwwMjIyLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW4iICsKICAgICAgInNpb25zXDAzMFwwMzIgXDAwMyhcdEJcMDAyXDAyMFwwMDA6e1xuXDAyNWZpZWxkX21lc3NhZ2VfbGlzdF8yNyIgKwogICAgICAiXDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaSIgKwogICAgICAidGhFeHRlbnNpb25zXDAzMFwwMzMgXDAwMyhcMDEzMiQucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8yTWVzc2FnZUJcMDAyXDAyMFwwMDA6U1xuXDAyM2ZpZWxkX2J5dGVzX2xpc3QiICsKICAgICAgIl8yOFwwMjIyLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImVXaXRoRXh0ZW5zaW9uc1wwMzBcMDM0IFwwMDMoXDAxNEJcMDAyXDAyMFwwMDA6VFxuXDAyNGZpZWxkX3VpbnQzIiArCiAgICAgICIyX2xpc3RfMjlcMDIyMi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yIiArCiAgICAgICJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwXDAzNSBcMDAzKFxyQlwwMDJcMDIwXDAwMDpcMjAxXDAwMVxuXDAyMmZpZWwiICsKICAgICAgImRfZW51bV9saXN0XzMwXDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zXDAzMFwwMzYgXDAwMyhcMDE2Mi0ucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZS5UZXN0RW51bUIiICsKICAgICAgIlwwMDJcMDIwXDAwMDpWXG5cMDI2ZmllbGRfc2ZpeGVkMzJfbGlzdF8zMVwwMjIyLnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uIiArCiAgICAgICJzXDAzMFwwMzcgXDAwMyhcMDE3QlwwMDJcMDIwXDAwMDpWXG5cMDI2ZmllbGRfc2ZpeGVkNjRfbGlzdF8zMlwwMjIyLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRSIgKwogICAgICAieHRlbnNpb25zXDAzMCAgXDAwMyhcMDIwQlwwMDJcMDIwXDAwMDpUXG5cMDI0ZmllbGRfc2ludDMyX2xpc3QiICsKICAgICAgIl8zM1wwMjIyLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWciICsKICAgICAgImVXaXRoRXh0ZW5zaW9uc1wwMzAhIFwwMDMoXDAyMUJcMDAyXDAyMFwwMDA6VFxuXDAyNGZpZWxkX3NpbnQ2IiArCiAgICAgICI0X2xpc3RfMzRcMDIyMi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yIiArCiAgICAgICJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwXCIgXDAwMyhcMDIyQlwwMDJcMDIwXDAwMDpbXG5cMDMzZmllbGQiICsKICAgICAgIl9kb3VibGVfbGlzdF9wYWNrZWRfMzVcMDIyMi5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwIyBcMDAzKFwwMDEiICsKICAgICAgIkJcMDAyXDAyMFwwMDE6WlxuXDAzMmZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2XDAyMjIucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlIiArCiAgICAgICJuc2lvbnNcMDMwJCBcMDAzKFwwMDJCXDAwMlwwMjBcMDAxOlpcblwwMzJmaWVsZF9pbnQ2NF9saXN0X3BhYyIgKwogICAgICAia2VkXzM3XDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lcyIgKwogICAgICAic2FnZVdpdGhFeHRlbnNpb25zXDAzMCUgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMTpbXG5cMDMzZmllbGRfdWkiICsKICAgICAgIm50NjRfbGlzdF9wYWNrZWRfMzhcMDIyMi5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwJiBcMDAzKFwwMDRCXDAwMlwwMjAiICsKICAgICAgIlwwMDE6WlxuXDAzMmZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5XDAyMjIucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpIiArCiAgICAgICJvbnNcMDMwXCcgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMTpcXFxuXDAzNGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrIiArCiAgICAgICJlZF80MFwwMjIyLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzIiArCiAgICAgICJhZ2VXaXRoRXh0ZW5zaW9uc1wwMzAoIFwwMDMoXDAwNkJcMDAyXDAyMFwwMDE6XFxcblwwMzRmaWVsZF9maXgiICsKICAgICAgImVkMzJfbGlzdF9wYWNrZWRfNDFcMDIyMi5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwKSBcMDAzKFwwMDdCXDAwMlwwMjAiICsKICAgICAgIlwwMDE6WVxuXDAzMWZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDJcMDIyMi5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvIiArCiAgICAgICJuc1wwMzAqIFwwMDMoXDAxMEJcMDAyXDAyMFwwMDE6W1xuXDAzM2ZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZCIgKwogICAgICAiXzQzXDAyMjIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZyIgKwogICAgICAiZVdpdGhFeHRlbnNpb25zXDAzMCsgXDAwMyhcckJcMDAyXDAyMFwwMDE6XDIxMFwwMDFcblwwMzFmaWVsZF9lbnVtIiArCiAgICAgICJfbGlzdF9wYWNrZWRfNDRcMDIyMi5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNcMDMwLCBcMDAzKFwwMTYyLS5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlLlRlc3RFbnVtIiArCiAgICAgICJCXDAwMlwwMjBcMDAxOl1cblwwMzVmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NVwwMjIyLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRSIgKwogICAgICAieHRlbnNpb25zXDAzMC0gXDAwMyhcMDE3QlwwMDJcMDIwXDAwMTpdXG5cMDM1ZmllbGRfc2ZpeGVkNjRfbGkiICsKICAgICAgInN0X3BhY2tlZF80NlwwMjIyLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm8iICsKICAgICAgInRvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc1wwMzAuIFwwMDMoXDAyMEJcMDAyXDAyMFwwMDE6W1xuXDAzM2ZpIiArCiAgICAgICJlbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3XDAyMjIucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zXDAzMC8gIiArCiAgICAgICJcMDAzKFwwMjFCXDAwMlwwMjBcMDAxOltcblwwMzNmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDhcMDIyMiIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzJNZXNzYWdlV2l0aCIgKwogICAgICAiRXh0ZW5zaW9uc1wwMzAwIFwwMDMoXDAyMkJcMDAyXDAyMFwwMDE6bVxuXDAxNGZpZWxkZ3JvdXA0OVwwMjIyLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXgiICsKICAgICAgInRlbnNpb25zXDAzMDEgXDAwMShcbjIjLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5GIiArCiAgICAgICJpZWxkR3JvdXA0OTp1XG5cMDIwZmllbGRncm91cGxpc3Q1MVwwMjIyLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaSIgKwogICAgICAib25zXDAzMDMgXDAwMyhcbjJcJy5wcm90b2J1Zi5leHBlcmltZW50YWwuRmllbGRHIiArCiAgICAgICJyb3VwTGlzdDUxQixcblwwMzNjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbiIgKwogICAgICAiZ0JcclByb3RvMlRlc3RpbmciCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yU3BlY2lhbEZpZWxkTmFtZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVndWxhck5hbWUiLCAiQ2FjaGVkU2l6ZV8iLCAiU2VyaWFsaXplZFNpemVfIiwgIkNsYXNzXyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZERvdWJsZTEiLCAiRmllbGRGbG9hdDIiLCAiRmllbGRJbnQ2NDMiLCAiRmllbGRVaW50NjQ0IiwgIkZpZWxkSW50MzI1IiwgIkZpZWxkRml4ZWQ2NDYiLCAiRmllbGRGaXhlZDMyNyIsICJGaWVsZEJvb2w4IiwgIkZpZWxkU3RyaW5nOSIsICJGaWVsZE1lc3NhZ2UxMCIsICJGaWVsZEJ5dGVzMTEiLCAiRmllbGRVaW50MzIxMiIsICJGaWVsZEVudW0xMyIsICJGaWVsZFNmaXhlZDMyMTQiLCAiRmllbGRTZml4ZWQ2NDE1IiwgIkZpZWxkU2ludDMyMTYiLCAiRmllbGRTaW50NjQxNyIsICJGaWVsZERvdWJsZUxpc3QxOCIsICJGaWVsZEZsb2F0TGlzdDE5IiwgIkZpZWxkSW50NjRMaXN0MjAiLCAiRmllbGRVaW50NjRMaXN0MjEiLCAiRmllbGRJbnQzMkxpc3QyMiIsICJGaWVsZEZpeGVkNjRMaXN0MjMiLCAiRmllbGRGaXhlZDMyTGlzdDI0IiwgIkZpZWxkQm9vbExpc3QyNSIsICJGaWVsZFN0cmluZ0xpc3QyNiIsICJGaWVsZE1lc3NhZ2VMaXN0MjciLCAiRmllbGRCeXRlc0xpc3QyOCIsICJGaWVsZFVpbnQzMkxpc3QyOSIsICJGaWVsZEVudW1MaXN0MzAiLCAiRmllbGRTZml4ZWQzMkxpc3QzMSIsICJGaWVsZFNmaXhlZDY0TGlzdDMyIiwgIkZpZWxkU2ludDMyTGlzdDMzIiwgIkZpZWxkU2ludDY0TGlzdDM0IiwgIkZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IiwgIkZpZWxkRmxvYXRMaXN0UGFja2VkMzYiLCAiRmllbGRJbnQ2NExpc3RQYWNrZWQzNyIsICJGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCIsICJGaWVsZEludDMyTGlzdFBhY2tlZDM5IiwgIkZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCIsICJGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEiLCAiRmllbGRCb29sTGlzdFBhY2tlZDQyIiwgIkZpZWxkVWludDMyTGlzdFBhY2tlZDQzIiwgIkZpZWxkRW51bUxpc3RQYWNrZWQ0NCIsICJGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1IiwgIkZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYiLCAiRmllbGRTaW50MzJMaXN0UGFja2VkNDciLCAiRmllbGRTaW50NjRMaXN0UGFja2VkNDgiLCAiRmllbGRHcm91cDQ5IiwgIkZpZWxkR3JvdXBMaXN0NTEiLCAiRmllbGREb3VibGU1MyIsICJGaWVsZEZsb2F0NTQiLCAiRmllbGRJbnQ2NDU1IiwgIkZpZWxkVWludDY0NTYiLCAiRmllbGRJbnQzMjU3IiwgIkZpZWxkRml4ZWQ2NDU4IiwgIkZpZWxkRml4ZWQzMjU5IiwgIkZpZWxkQm9vbDYwIiwgIkZpZWxkU3RyaW5nNjEiLCAiRmllbGRNZXNzYWdlNjIiLCAiRmllbGRCeXRlczYzIiwgIkZpZWxkVWludDMyNjQiLCAiRmllbGRTZml4ZWQzMjY1IiwgIkZpZWxkU2ZpeGVkNjQ2NiIsICJGaWVsZFNpbnQzMjY3IiwgIkZpZWxkU2ludDY0NjgiLCAiRmllbGRHcm91cDY5IiwgIkZpZWxkUmVxdWlyZWREb3VibGU3MSIsICJGaWVsZFJlcXVpcmVkRmxvYXQ3MiIsICJGaWVsZFJlcXVpcmVkSW50NjQ3MyIsICJGaWVsZFJlcXVpcmVkVWludDY0NzQiLCAiRmllbGRSZXF1aXJlZEludDMyNzUiLCAiRmllbGRSZXF1aXJlZEZpeGVkNjQ3NiIsICJGaWVsZFJlcXVpcmVkRml4ZWQzMjc3IiwgIkZpZWxkUmVxdWlyZWRCb29sNzgiLCAiRmllbGRSZXF1aXJlZFN0cmluZzc5IiwgIkZpZWxkUmVxdWlyZWRNZXNzYWdlODAiLCAiRmllbGRSZXF1aXJlZEJ5dGVzODEiLCAiRmllbGRSZXF1aXJlZFVpbnQzMjgyIiwgIkZpZWxkUmVxdWlyZWRFbnVtODMiLCAiRmllbGRSZXF1aXJlZFNmaXhlZDMyODQiLCAiRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUiLCAiRmllbGRSZXF1aXJlZFNpbnQzMjg2IiwgIkZpZWxkUmVxdWlyZWRTaW50NjQ4NyIsICJGaWVsZFJlcXVpcmVkR3JvdXA4OCIsICJUZXN0T25lb2YiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXA0OV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZpZWxkSW50MzI1MCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkR3JvdXBMaXN0NTFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGRJbnQzMjUyIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cDY5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9GaWVsZEdyb3VwNjlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRHcm91cDY5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZEludDMyNzAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX1JlcXVpcmVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VfRmllbGRSZXF1aXJlZEdyb3VwODhfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkUmVxdWlyZWRHcm91cDg4X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlX0ZpZWxkUmVxdWlyZWRHcm91cDg4X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZEludDMyODkiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yRW1wdHlfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMkVtcHR5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJFbXB0eV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhFeHRlbnNpb25zX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoRXh0ZW5zaW9uc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfRmllbGRHcm91cDQ5X2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9GaWVsZEdyb3VwNDlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX0ZpZWxkR3JvdXA0OV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGRJbnQzMjUwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX0ZpZWxkR3JvdXBMaXN0NTFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZpZWxkSW50MzI1MiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZE1hcEJvb2xCb29sMSIsICJGaWVsZE1hcEJvb2xCeXRlczIiLCAiRmllbGRNYXBCb29sRG91YmxlMyIsICJGaWVsZE1hcEJvb2xFbnVtNCIsICJGaWVsZE1hcEJvb2xGaXhlZDMyNSIsICJGaWVsZE1hcEJvb2xGaXhlZDY0NiIsICJGaWVsZE1hcEJvb2xGbG9hdDciLCAiRmllbGRNYXBCb29sSW50MzI4IiwgIkZpZWxkTWFwQm9vbEludDY0OSIsICJGaWVsZE1hcEJvb2xNZXNzYWdlMTAiLCAiRmllbGRNYXBCb29sU2ZpeGVkMzIxMSIsICJGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyIiwgIkZpZWxkTWFwQm9vbFNpbnQzMjEzIiwgIkZpZWxkTWFwQm9vbFNpbnQ2NDE0IiwgIkZpZWxkTWFwQm9vbFN0cmluZzE1IiwgIkZpZWxkTWFwQm9vbFVpbnQzMjE2IiwgIkZpZWxkTWFwQm9vbFVpbnQ2NDE3IiwgIkZpZWxkTWFwRml4ZWQzMkJvb2wxOCIsICJGaWVsZE1hcEZpeGVkMzJCeXRlczE5IiwgIkZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwIiwgIkZpZWxkTWFwRml4ZWQzMkVudW0yMSIsICJGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIiLCAiRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzIiwgIkZpZWxkTWFwRml4ZWQzMkZsb2F0MjQiLCAiRmllbGRNYXBGaXhlZDMySW50MzIyNSIsICJGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2IiwgIkZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNyIsICJGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4IiwgIkZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkiLCAiRmllbGRNYXBGaXhlZDMyU2ludDMyMzAiLCAiRmllbGRNYXBGaXhlZDMyU2ludDY0MzEiLCAiRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIiLCAiRmllbGRNYXBGaXhlZDMyVWludDMyMzMiLCAiRmllbGRNYXBGaXhlZDMyVWludDY0MzQiLCAiRmllbGRNYXBGaXhlZDY0Qm9vbDM1IiwgIkZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYiLCAiRmllbGRNYXBGaXhlZDY0RG91YmxlMzciLCAiRmllbGRNYXBGaXhlZDY0RW51bTM4IiwgIkZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSIsICJGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAiLCAiRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSIsICJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyIiwgIkZpZWxkTWFwRml4ZWQ2NEludDY0NDMiLCAiRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0IiwgIkZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUiLCAiRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NiIsICJGaWVsZE1hcEZpeGVkNjRTaW50MzI0NyIsICJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCIsICJGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSIsICJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCIsICJGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSIsICJGaWVsZE1hcEludDMyQm9vbDUyIiwgIkZpZWxkTWFwSW50MzJCeXRlczUzIiwgIkZpZWxkTWFwSW50MzJEb3VibGU1NCIsICJGaWVsZE1hcEludDMyRW51bTU1IiwgIkZpZWxkTWFwSW50MzJGaXhlZDMyNTYiLCAiRmllbGRNYXBJbnQzMkZpeGVkNjQ1NyIsICJGaWVsZE1hcEludDMyRmxvYXQ1OCIsICJGaWVsZE1hcEludDMySW50MzI1OSIsICJGaWVsZE1hcEludDMySW50NjQ2MCIsICJGaWVsZE1hcEludDMyTWVzc2FnZTYxIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQzMjYyIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzIiwgIkZpZWxkTWFwSW50MzJTaW50MzI2NCIsICJGaWVsZE1hcEludDMyU2ludDY0NjUiLCAiRmllbGRNYXBJbnQzMlN0cmluZzY2IiwgIkZpZWxkTWFwSW50MzJVaW50MzI2NyIsICJGaWVsZE1hcEludDMyVWludDY0NjgiLCAiRmllbGRNYXBJbnQ2NEJvb2w2OSIsICJGaWVsZE1hcEludDY0Qnl0ZXM3MCIsICJGaWVsZE1hcEludDY0RG91YmxlNzEiLCAiRmllbGRNYXBJbnQ2NEVudW03MiIsICJGaWVsZE1hcEludDY0Rml4ZWQzMjczIiwgIkZpZWxkTWFwSW50NjRGaXhlZDY0NzQiLCAiRmllbGRNYXBJbnQ2NEZsb2F0NzUiLCAiRmllbGRNYXBJbnQ2NEludDMyNzYiLCAiRmllbGRNYXBJbnQ2NEludDY0NzciLCAiRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCIsICJGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSIsICJGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCIsICJGaWVsZE1hcEludDY0U2ludDMyODEiLCAiRmllbGRNYXBJbnQ2NFNpbnQ2NDgyIiwgIkZpZWxkTWFwSW50NjRTdHJpbmc4MyIsICJGaWVsZE1hcEludDY0VWludDMyODQiLCAiRmllbGRNYXBJbnQ2NFVpbnQ2NDg1IiwgIkZpZWxkTWFwU2ZpeGVkMzJCb29sODYiLCAiRmllbGRNYXBTZml4ZWQzMkJ5dGVzODciLCAiRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4IiwgIkZpZWxkTWFwU2ZpeGVkMzJFbnVtODkiLCAiRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCIsICJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxIiwgIkZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0IiwgIkZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTciLCAiRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4IiwgIkZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSIsICJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwIiwgIkZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEiLCAiRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMiIsICJGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMyIsICJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQiLCAiRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSIsICJGaWVsZE1hcFNmaXhlZDY0RW51bTEwNiIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNyIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCIsICJGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkiLCAiRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwIiwgIkZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSIsICJGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMiIsICJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMiLCAiRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0IiwgIkZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUiLCAiRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNiIsICJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3IiwgIkZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgiLCAiRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSIsICJGaWVsZE1hcFNpbnQzMkJvb2wxMjAiLCAiRmllbGRNYXBTaW50MzJCeXRlczEyMSIsICJGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMiIsICJGaWVsZE1hcFNpbnQzMkVudW0xMjMiLCAiRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0IiwgIkZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSIsICJGaWVsZE1hcFNpbnQzMkZsb2F0MTI2IiwgIkZpZWxkTWFwU2ludDMySW50MzIxMjciLCAiRmllbGRNYXBTaW50MzJJbnQ2NDEyOCIsICJGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkiLCAiRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCIsICJGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxIiwgIkZpZWxkTWFwU2ludDMyU2ludDMyMTMyIiwgIkZpZWxkTWFwU2ludDMyU2ludDY0MTMzIiwgIkZpZWxkTWFwU2ludDMyU3RyaW5nMTM0IiwgIkZpZWxkTWFwU2ludDMyVWludDMyMTM1IiwgIkZpZWxkTWFwU2ludDMyVWludDY0MTM2IiwgIkZpZWxkTWFwU2ludDY0Qm9vbDEzNyIsICJGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4IiwgIkZpZWxkTWFwU2ludDY0RG91YmxlMTM5IiwgIkZpZWxkTWFwU2ludDY0RW51bTE0MCIsICJGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEiLCAiRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyIiwgIkZpZWxkTWFwU2ludDY0RmxvYXQxNDMiLCAiRmllbGRNYXBTaW50NjRJbnQzMjE0NCIsICJGaWVsZE1hcFNpbnQ2NEludDY0MTQ1IiwgIkZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NiIsICJGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3IiwgIkZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgiLCAiRmllbGRNYXBTaW50NjRTaW50MzIxNDkiLCAiRmllbGRNYXBTaW50NjRTaW50NjQxNTAiLCAiRmllbGRNYXBTaW50NjRTdHJpbmcxNTEiLCAiRmllbGRNYXBTaW50NjRVaW50MzIxNTIiLCAiRmllbGRNYXBTaW50NjRVaW50NjQxNTMiLCAiRmllbGRNYXBTdHJpbmdCb29sMTU0IiwgIkZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUiLCAiRmllbGRNYXBTdHJpbmdEb3VibGUxNTYiLCAiRmllbGRNYXBTdHJpbmdFbnVtMTU3IiwgIkZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCIsICJGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkiLCAiRmllbGRNYXBTdHJpbmdGbG9hdDE2MCIsICJGaWVsZE1hcFN0cmluZ0ludDMyMTYxIiwgIkZpZWxkTWFwU3RyaW5nSW50NjQxNjIiLCAiRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzIiwgIkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQiLCAiRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSIsICJGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NiIsICJGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NyIsICJGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCIsICJGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSIsICJGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCIsICJGaWVsZE1hcFVpbnQzMkJvb2wxNzEiLCAiRmllbGRNYXBVaW50MzJCeXRlczE3MiIsICJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MyIsICJGaWVsZE1hcFVpbnQzMkVudW0xNzQiLCAiRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1IiwgIkZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NiIsICJGaWVsZE1hcFVpbnQzMkZsb2F0MTc3IiwgIkZpZWxkTWFwVWludDMySW50MzIxNzgiLCAiRmllbGRNYXBVaW50MzJJbnQ2NDE3OSIsICJGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAiLCAiRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSIsICJGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyIiwgIkZpZWxkTWFwVWludDMyU2ludDMyMTgzIiwgIkZpZWxkTWFwVWludDMyU2ludDY0MTg0IiwgIkZpZWxkTWFwVWludDMyU3RyaW5nMTg1IiwgIkZpZWxkTWFwVWludDMyVWludDMyMTg2IiwgIkZpZWxkTWFwVWludDMyVWludDY0MTg3IiwgIkZpZWxkTWFwVWludDY0Qm9vbDE4OCIsICJGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5IiwgIkZpZWxkTWFwVWludDY0RG91YmxlMTkwIiwgIkZpZWxkTWFwVWludDY0RW51bTE5MSIsICJGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIiLCAiRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzIiwgIkZpZWxkTWFwVWludDY0RmxvYXQxOTQiLCAiRmllbGRNYXBVaW50NjRJbnQzMjE5NSIsICJGaWVsZE1hcFVpbnQ2NEludDY0MTk2IiwgIkZpZWxkTWFwVWludDY0TWVzc2FnZTE5NyIsICJGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4IiwgIkZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkiLCAiRmllbGRNYXBVaW50NjRTaW50MzIyMDAiLCAiRmllbGRNYXBVaW50NjRTaW50NjQyMDEiLCAiRmllbGRNYXBVaW50NjRTdHJpbmcyMDIiLCAiRmllbGRNYXBVaW50NjRVaW50MzIyMDMiLCAiRmllbGRNYXBVaW50NjRVaW50NjQyMDQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQm9vbDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQnl0ZXMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEVudW00RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50MzI4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDMyMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDMyMzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDM4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50NjQ0M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDY0NTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQzMjU2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDY1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTA0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDExMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCb29sMTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTMwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTM3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTY0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTcxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTg4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTkzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8yTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvMk1lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzJNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBmaWVsZERvdWJsZTEuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBmaWVsZEZsb2F0Mi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEpKTsKICAgIGZpZWxkSW50NjQzLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMikpOwogICAgZmllbGRVaW50NjQ0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMykpOwogICAgZmllbGRJbnQzMjUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0KSk7CiAgICBmaWVsZEZpeGVkNjQ2LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNSkpOwogICAgZmllbGRGaXhlZDMyNy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDYpKTsKICAgIGZpZWxkQm9vbDguaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3KSk7CiAgICBmaWVsZFN0cmluZzkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg4KSk7CiAgICBmaWVsZE1lc3NhZ2UxMC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDkpKTsKICAgIGZpZWxkQnl0ZXMxMS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEwKSk7CiAgICBmaWVsZFVpbnQzMjEyLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTEpKTsKICAgIGZpZWxkRW51bTEzLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTIpKTsKICAgIGZpZWxkU2ZpeGVkMzIxNC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEzKSk7CiAgICBmaWVsZFNmaXhlZDY0MTUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxNCkpOwogICAgZmllbGRTaW50MzIxNi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE1KSk7CiAgICBmaWVsZFNpbnQ2NDE3LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTYpKTsKICAgIGZpZWxkRG91YmxlTGlzdDE4LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTcpKTsKICAgIGZpZWxkRmxvYXRMaXN0MTkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxOCkpOwogICAgZmllbGRJbnQ2NExpc3QyMC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE5KSk7CiAgICBmaWVsZFVpbnQ2NExpc3QyMS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDIwKSk7CiAgICBmaWVsZEludDMyTGlzdDIyLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjEpKTsKICAgIGZpZWxkRml4ZWQ2NExpc3QyMy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDIyKSk7CiAgICBmaWVsZEZpeGVkMzJMaXN0MjQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyMykpOwogICAgZmllbGRCb29sTGlzdDI1LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjQpKTsKICAgIGZpZWxkU3RyaW5nTGlzdDI2LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjUpKTsKICAgIGZpZWxkTWVzc2FnZUxpc3QyNy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI2KSk7CiAgICBmaWVsZEJ5dGVzTGlzdDI4LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjcpKTsKICAgIGZpZWxkVWludDMyTGlzdDI5LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjgpKTsKICAgIGZpZWxkRW51bUxpc3QzMC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI5KSk7CiAgICBmaWVsZFNmaXhlZDMyTGlzdDMxLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzApKTsKICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzIuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMSkpOwogICAgZmllbGRTaW50MzJMaXN0MzMuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMikpOwogICAgZmllbGRTaW50NjRMaXN0MzQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMykpOwogICAgZmllbGREb3VibGVMaXN0UGFja2VkMzUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzNCkpOwogICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDM1KSk7CiAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzYpKTsKICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzcpKTsKICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzOCkpOwogICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzkpKTsKICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQwKSk7CiAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDIuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0MSkpOwogICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0MikpOwogICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDMpKTsKICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0NCkpOwogICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ1KSk7CiAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ2KSk7CiAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ3KSk7CiAgICBmaWVsZEdyb3VwNDkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0OCkpOwogICAgZmllbGRHcm91cExpc3Q1MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ5KSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQDcAmNv0OQzANDkMwAyAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL1Byb3RvMlRlc3RpbmdMaXRlLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8yX21lc3NhZ2VfbGl0ZS5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nOwoKcHVibGljIGZpbmFsIGNsYXNzIFByb3RvMlRlc3RpbmdMaXRlIHsKICBwcml2YXRlIFByb3RvMlRlc3RpbmdMaXRlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZERvdWJsZTEpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZEZsb2F0Mik7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkSW50NjQzKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRVaW50NjQ0KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRJbnQzMjUpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZEZpeGVkNjQ2KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRGaXhlZDMyNyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkQm9vbDgpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZFN0cmluZzkpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZE1lc3NhZ2UxMCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkQnl0ZXMxMSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkVWludDMyMTIpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZEVudW0xMyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ZpeGVkMzIxNCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ZpeGVkNjQxNSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ludDMyMTYpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZFNpbnQ2NDE3KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGREb3VibGVMaXN0MTgpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZEZsb2F0TGlzdDE5KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRJbnQ2NExpc3QyMCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkVWludDY0TGlzdDIxKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRJbnQzMkxpc3QyMik7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkRml4ZWQ2NExpc3QyMyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkRml4ZWQzMkxpc3QyNCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkQm9vbExpc3QyNSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU3RyaW5nTGlzdDI2KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRNZXNzYWdlTGlzdDI3KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRCeXRlc0xpc3QyOCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkVWludDMyTGlzdDI5KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRFbnVtTGlzdDMwKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRTZml4ZWQzMkxpc3QzMSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ZpeGVkNjRMaXN0MzIpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZFNpbnQzMkxpc3QzMyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ludDY0TGlzdDM0KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGREb3VibGVMaXN0UGFja2VkMzUpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZEZsb2F0TGlzdFBhY2tlZDM2KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRJbnQ2NExpc3RQYWNrZWQzNyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRJbnQzMkxpc3RQYWNrZWQzOSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkQm9vbExpc3RQYWNrZWQ0Mik7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkVWludDMyTGlzdFBhY2tlZDQzKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRFbnVtTGlzdFBhY2tlZDQ0KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYpOwogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0Nyk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRHcm91cDQ5KTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuZmllbGRHcm91cExpc3Q1MSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGREb3VibGUxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTEuCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZERvdWJsZTEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZpZWxkX2Zsb2F0XzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRmxvYXQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZpZWxkX2Zsb2F0XzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQyLgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZEZsb2F0MigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQ2NDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NDMuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRJbnQ2NDMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDY0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZmllbGRfdWludDY0XzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFVpbnQ2NDQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkSW50MzI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQ2NDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRml4ZWQ2NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBmaWVsZF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDYuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRGaXhlZDY0NigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDMyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNy4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMjcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQm9vbDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkQm9vbDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbDguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sOCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTdHJpbmc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmc5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlMTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRNZXNzYWdlMTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2UxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTEwT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzMTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzMTEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyMTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDMyMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyMTIuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMjEyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRFbnVtMTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRW51bTEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtMTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW0xMygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkMzIxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMjE0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMjE0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDE1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0MTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0MTUuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDE1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZmllbGRfc2ludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQzMjE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNpbnQzMjE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMjE2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzIxNigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTaW50NjQxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNpbnQ2NDE3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRG91YmxlTGlzdDE4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdDE4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdDE4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZsb2F0TGlzdDE5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdDE5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3QyMC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDY0TGlzdDIwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdDIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdDIxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQ2NExpc3QyMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3QyMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDMyTGlzdDIyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0MjMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0MjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRCb29sTGlzdDI1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdDI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0MjUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZ0xpc3QyNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZ0xpc3QyNkJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gCiAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCeXRlc0xpc3QyOC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlc0xpc3QyOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzTGlzdDI4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0MjkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3QyOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3QyOShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3QzMExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkNjRMaXN0MzIuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50MzJMaXN0MzMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzMyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjRMaXN0MzQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ludDY0TGlzdDM0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgaW50IGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzgoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDgoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkZ3JvdXA0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRHcm91cDQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZGdyb3VwNDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgZ2V0RmllbGRHcm91cDQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDlPckJ1aWxkZXIgZ2V0RmllbGRHcm91cDQ5T3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTE+IAogICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBnZXRGaWVsZEdyb3VwTGlzdDUxKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRHcm91cExpc3Q1MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXI+IAogICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGREb3VibGU1MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGbG9hdDU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZEZsb2F0NTQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkSW50NjQ1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0NTUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDY0NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NTYuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjU3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjU3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQ2NDU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ1OC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjQ1OCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNTkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzI1OSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRCb29sNjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sNjAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU3RyaW5nNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nNjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTYyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNZXNzYWdlNjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2U2Mk9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQnl0ZXM2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRCeXRlczYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlczYzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczYzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFVpbnQzMjY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMjY0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50MzI2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkMzI2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMjY1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMjY1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDY2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0NjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0NjYuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDY2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQzMjY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNpbnQzMjY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMjY3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzI2NygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQ2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTaW50NjQ2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQ2OC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNpbnQ2NDY4KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZGdyb3VwNjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkR3JvdXA2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRncm91cDY5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IGdldEZpZWxkR3JvdXA2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5T3JCdWlsZGVyIGdldEZpZWxkR3JvdXA2OU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIGZpZWxkX3JlcXVpcmVkX2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZERvdWJsZTcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIGZpZWxkX3JlcXVpcmVkX2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWREb3VibGU3MS4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZmxvYXQgZmllbGRfcmVxdWlyZWRfZmxvYXRfNzIgPSA3Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRGbG9hdDcyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmbG9hdCBmaWVsZF9yZXF1aXJlZF9mbG9hdF83MiA9IDcyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRGbG9hdDcyLgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50NjQgZmllbGRfcmVxdWlyZWRfaW50NjRfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRJbnQ2NDczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkSW50NjQ3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQ2NCBmaWVsZF9yZXF1aXJlZF9pbnQ2NF83MyA9IDczOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRJbnQ2NDczLgogICAgICovCiAgICBsb25nIGdldEZpZWxkUmVxdWlyZWRJbnQ2NDczKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50NjQgZmllbGRfcmVxdWlyZWRfdWludDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkVWludDY0NzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50NjQgZmllbGRfcmVxdWlyZWRfdWludDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0LgogICAgICovCiAgICBsb25nIGdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgZmllbGRfcmVxdWlyZWRfaW50MzJfNzUgPSA3NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRJbnQzMjc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBmaWVsZF9yZXF1aXJlZF9pbnQzMl83NSA9IDc1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRJbnQzMjc1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRSZXF1aXJlZEludDMyNzUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkNjQgZmllbGRfcmVxdWlyZWRfZml4ZWQ2NF83NiA9IDc2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEZpeGVkNjQ3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX2ZpeGVkNjRfNzYgPSA3Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2LgogICAgICovCiAgICBsb25nIGdldEZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgZmllbGRfcmVxdWlyZWRfZml4ZWQzMl83NyA9IDc3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEZpeGVkMzI3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRSZXF1aXJlZEZpeGVkMzI3NygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYm9vbCBmaWVsZF9yZXF1aXJlZF9ib29sXzc4ID0gNzg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkQm9vbDc4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJvb2wgZmllbGRfcmVxdWlyZWRfYm9vbF83OCA9IDc4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRCb29sNzguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRSZXF1aXJlZEJvb2w3OCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFN0cmluZzc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTdHJpbmc3OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFJlcXVpcmVkU3RyaW5nNzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkUmVxdWlyZWRTdHJpbmc3OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRNZXNzYWdlODAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyBmaWVsZF9yZXF1aXJlZF9ieXRlc184MSA9IDgxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEJ5dGVzODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEJ5dGVzODEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQzMjgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkVWludDMyODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRVaW50MzI4Mi4KICAgICAqLwogICAgaW50IGdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRFbnVtODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRW51bTgzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRSZXF1aXJlZEVudW04MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkMzIgZmllbGRfcmVxdWlyZWRfc2ZpeGVkMzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9zZml4ZWQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX3NmaXhlZDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkNjQgZmllbGRfcmVxdWlyZWRfc2ZpeGVkNjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NS4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDMyIGZpZWxkX3JlcXVpcmVkX3NpbnQzMl84NiA9IDg2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNpbnQzMjg2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ludDMyODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDMyIGZpZWxkX3JlcXVpcmVkX3NpbnQzMl84NiA9IDg2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTaW50MzI4Ni4KICAgICAqLwogICAgaW50IGdldEZpZWxkUmVxdWlyZWRTaW50MzI4NigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDY0IGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84NyA9IDg3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNpbnQ2NDg3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDY0IGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84NyA9IDg3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTaW50NjQ4Ny4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRyZXF1aXJlZGdyb3VwODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRHcm91cDg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkcmVxdWlyZWRncm91cDg4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggZ2V0RmllbGRSZXF1aXJlZEdyb3VwODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZ3JvdXAgRmllbGRSZXF1aXJlZEdyb3VwODggPSA4OCB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIoKTsKCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdE9uZW9mQ2FzZSBnZXRUZXN0T25lb2ZDYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvdG8yTWVzc2FnZUxpdGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUpCiAgICAgIFByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQcm90bzJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzJNZXNzYWdlTGl0ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvMk1lc3NhZ2VMaXRlKCkgewogICAgICBmaWVsZFN0cmluZzlfID0gIiI7CiAgICAgIGZpZWxkQnl0ZXMxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBmaWVsZEZsb2F0TGlzdDE5XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFVpbnQ2NExpc3QyMV8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkSW50MzJMaXN0MjJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRCb29sTGlzdDI1XyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgZmllbGRVaW50MzJMaXN0MjlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRW51bUxpc3QzMF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFNpbnQzMkxpc3QzM18gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRHcm91cExpc3Q1MV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSAiIjsKICAgICAgZmllbGRSZXF1aXJlZEJ5dGVzODFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICBmaWVsZFJlcXVpcmVkRW51bTgzXyA9IDA7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUHJvdG8yTWVzc2FnZUxpdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFRlc3RFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgWkVSTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk9ORSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgT05FKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+VFdPID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBUV08oMiksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5aRVJPID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBaRVJPX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk9ORSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRXTyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFdPX1ZBTFVFID0gMjsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gWkVSTzsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIE9ORTsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIFRXTzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgVGVzdEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFRlc3RFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBUZXN0RW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUZXN0RW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIFRlc3RFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBGaWVsZEdyb3VwNDlPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNGaWVsZEludDMyNTAoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTAuCiAgICAgICAqLwogICAgICBpbnQgZ2V0RmllbGRJbnQzMjUwKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZEdyb3VwNDkgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSkKICAgICAgICBGaWVsZEdyb3VwNDlPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBGaWVsZEdyb3VwNDkubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBGaWVsZEdyb3VwNDkoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBGaWVsZEdyb3VwNDkoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgRmllbGRHcm91cDQ5KCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXA0OV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXA0OV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81MF9GSUVMRF9OVU1CRVIgPSA1MDsKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMjUwXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUwLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1MCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMjUwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDUwLCBmaWVsZEludDMyNTBfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNTAsIGZpZWxkSW50MzI1MF8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5KSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkpIG9iajsKCiAgICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1MCgpICE9IG90aGVyLmhhc0ZpZWxkSW50MzI1MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1MCgpKSB7CiAgICAgICAgICBpZiAoZ2V0RmllbGRJbnQzMjUwKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEludDMyNTAoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1MCgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl81MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNTAoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDl9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSkKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDlPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDQ5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5LkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBmaWVsZEludDMyNTBfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgYnVpbGQoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyNTBfID0gZmllbGRJbnQzMjUwXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRJbnQzMjUwKCkpIHsKICAgICAgICAgICAgc2V0RmllbGRJbnQzMjUwKG90aGVyLmdldEZpZWxkSW50MzI1MCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDAwOiB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzI1MF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA0MDAKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1MF8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUwIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUwKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTAuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUwKCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI1MF87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjUwIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjUwKGludCB2YWx1ZSkgewoKICAgICAgICAgIGZpZWxkSW50MzI1MF8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI1MCgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGZpZWxkSW50MzI1MF8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cDQ5PgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RmllbGRHcm91cDQ5PigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEZpZWxkR3JvdXA0OSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA0OT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA0OT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0ZpZWxkSW50MzI1MigpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Mi4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZEludDMyNTIoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZEdyb3VwTGlzdDUxIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxKQogICAgICAgIEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBGaWVsZEdyb3VwTGlzdDUxLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgRmllbGRHcm91cExpc3Q1MShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIEZpZWxkR3JvdXBMaXN0NTEoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgRmllbGRHcm91cExpc3Q1MSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cExpc3Q1MV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyXzUyX0ZJRUxEX05VTUJFUiA9IDUyOwogICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTJfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUyKCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyNTJfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNTIsIGZpZWxkSW50MzI1Ml8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg1MiwgZmllbGRJbnQzMjUyXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSkgb2JqOwoKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjUyKCkgIT0gb3RoZXIuaGFzRmllbGRJbnQzMjUyKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjUyKCkpIHsKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyNTIoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI1MigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjUyKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzUyX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzI1MigpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxKQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXBMaXN0NTFfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGZpZWxkSW50MzI1Ml8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgYnVpbGQoKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI1Ml8gPSBmaWVsZEludDMyNTJfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRJbnQzMjUyKCkpIHsKICAgICAgICAgICAgc2V0RmllbGRJbnQzMjUyKG90aGVyLmdldEZpZWxkSW50MzI1MigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDE2OiB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzI1Ml8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTYKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1Ml8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUyIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUyKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTIuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUyKCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI1Ml87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjUyIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjUyKGludCB2YWx1ZSkgewoKICAgICAgICAgIGZpZWxkSW50MzI1Ml8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI1MigpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGZpZWxkSW50MzI1Ml8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwTGlzdDUxPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RmllbGRHcm91cExpc3Q1MT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBGaWVsZEdyb3VwTGlzdDUxIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cExpc3Q1MT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXBMaXN0NTE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEZpZWxkR3JvdXA2OU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0ZpZWxkSW50MzI3MCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI3MC4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZEludDMyNzAoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkR3JvdXA2OSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5KQogICAgICAgIEZpZWxkR3JvdXA2OU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIEZpZWxkR3JvdXA2OS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIEZpZWxkR3JvdXA2OShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIEZpZWxkR3JvdXA2OSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBGaWVsZEdyb3VwNjkoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDY5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDY5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyXzcwX0ZJRUxEX05VTUJFUiA9IDcwOwogICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNzBfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI3MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNzAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjcwKCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyNzBfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNzAsIGZpZWxkSW50MzI3MF8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg3MCwgZmllbGRJbnQzMjcwXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkgb2JqOwoKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjcwKCkgIT0gb3RoZXIuaGFzRmllbGRJbnQzMjcwKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjcwKCkpIHsKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyNzAoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI3MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjcwKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzcwX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzI3MCgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5KQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXA2OV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNjlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGZpZWxkSW50MzI3MF8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXA2OV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI3MF8gPSBmaWVsZEludDMyNzBfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5KW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEludDMyNzAoKSkgewogICAgICAgICAgICBzZXRGaWVsZEludDMyNzAob3RoZXIuZ2V0RmllbGRJbnQzMjcwKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA1NjA6IHsKICAgICAgICAgICAgICAgICAgZmllbGRJbnQzMjcwXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDU2MAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMjcwXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNzAgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNzAoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI3MC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNzAoKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRJbnQzMjcwXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyNzAgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyNzAoaW50IHZhbHVlKSB7CgogICAgICAgICAgZmllbGRJbnQzMjcwXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMjcwKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgZmllbGRJbnQzMjcwXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwNjk+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGaWVsZEdyb3VwNjk+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRmllbGRHcm91cDY5IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cDY5PiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cDY5PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIFJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNWYWx1ZSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBpbnQgZ2V0VmFsdWUoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlcXVpcmVkTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKQogICAgICAgIFJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIFJlcXVpcmVkTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIFJlcXVpcmVkTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIFJlcXVpcmVkTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBSZXF1aXJlZE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfUmVxdWlyZWROZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfUmVxdWlyZWROZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNWYWx1ZSgpICE9IG90aGVyLmhhc1ZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgICAgaWYgKGdldFZhbHVlKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfUmVxdWlyZWROZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX1JlcXVpcmVkTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LnZhbHVlXyA9IHZhbHVlXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzVmFsdWUoKSkgewogICAgICAgICAgICBzZXRWYWx1ZShvdGhlci5nZXRWYWx1ZSgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICB2YWx1ZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCB2YWx1ZV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VmFsdWUoaW50IHZhbHVlKSB7CgogICAgICAgICAgdmFsdWVfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcXVpcmVkTmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlcXVpcmVkTmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBSZXF1aXJlZE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXF1aXJlZE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXF1aXJlZE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzg5ID0gODk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI4OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0ZpZWxkSW50MzI4OSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI4OS4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZEludDMyODkoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODh9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRSZXF1aXJlZEdyb3VwODggZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4KQogICAgICAgIEZpZWxkUmVxdWlyZWRHcm91cDg4T3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgRmllbGRSZXF1aXJlZEdyb3VwODgubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBGaWVsZFJlcXVpcmVkR3JvdXA4OChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIEZpZWxkUmVxdWlyZWRHcm91cDg4KCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IEZpZWxkUmVxdWlyZWRHcm91cDg4KCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkUmVxdWlyZWRHcm91cDg4X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRSZXF1aXJlZEdyb3VwODhfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODguQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyXzg5X0ZJRUxEX05VTUJFUiA9IDg5OwogICAgICBwcml2YXRlIGludCBmaWVsZEludDMyODlfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzg5ID0gODk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI4OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI4OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzg5ID0gODk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyODkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjg5KCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyODlfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoODksIGZpZWxkSW50MzI4OV8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg4OSwgZmllbGRJbnQzMjg5Xyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCkgb2JqOwoKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjg5KCkgIT0gb3RoZXIuaGFzRmllbGRJbnQzMjg5KCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjg5KCkpIHsKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyODkoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI4OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzRmllbGRJbnQzMjg5KCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzg5X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzI4OSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODh9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4KQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4T3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRSZXF1aXJlZEdyb3VwODhfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRSZXF1aXJlZEdyb3VwODhfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4LkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGZpZWxkSW50MzI4OV8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkUmVxdWlyZWRHcm91cDg4X2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IGJ1aWxkKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODgodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI4OV8gPSBmaWVsZEludDMyODlfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4KSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODguZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkSW50MzI4OSgpKSB7CiAgICAgICAgICAgIHNldEZpZWxkSW50MzI4OShvdGhlci5nZXRGaWVsZEludDMyODkoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDcxMjogewogICAgICAgICAgICAgICAgICBmaWVsZEludDMyODlfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNzEyCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBmaWVsZEludDMyODlfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl84OSA9IDg5OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI4OSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI4OSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfODkgPSA4OTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjg5LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI4OSgpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEludDMyODlfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl84OSA9IDg5OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI4OSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzI4OShpbnQgdmFsdWUpIHsKCiAgICAgICAgICBmaWVsZEludDMyODlfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl84OSA9IDg5OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyODkoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBmaWVsZEludDMyODlfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODgpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4IERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODgoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZFJlcXVpcmVkR3JvdXA4OD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZpZWxkUmVxdWlyZWRHcm91cDg4PigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEZpZWxkUmVxdWlyZWRHcm91cDg4IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRSZXF1aXJlZEdyb3VwODg+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZFJlcXVpcmVkR3JvdXA4OD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKICAgIHByaXZhdGUgaW50IHRlc3RPbmVvZkNhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHRlc3RPbmVvZl87CiAgICBwdWJsaWMgZW51bSBUZXN0T25lb2ZDYXNlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICAgIEZJRUxEX0RPVUJMRV81Myg1MyksCiAgICAgIEZJRUxEX0ZMT0FUXzU0KDU0KSwKICAgICAgRklFTERfSU5UNjRfNTUoNTUpLAogICAgICBGSUVMRF9VSU5UNjRfNTYoNTYpLAogICAgICBGSUVMRF9JTlQzMl81Nyg1NyksCiAgICAgIEZJRUxEX0ZJWEVENjRfNTgoNTgpLAogICAgICBGSUVMRF9GSVhFRDMyXzU5KDU5KSwKICAgICAgRklFTERfQk9PTF82MCg2MCksCiAgICAgIEZJRUxEX1NUUklOR182MSg2MSksCiAgICAgIEZJRUxEX01FU1NBR0VfNjIoNjIpLAogICAgICBGSUVMRF9CWVRFU182Myg2MyksCiAgICAgIEZJRUxEX1VJTlQzMl82NCg2NCksCiAgICAgIEZJRUxEX1NGSVhFRDMyXzY1KDY1KSwKICAgICAgRklFTERfU0ZJWEVENjRfNjYoNjYpLAogICAgICBGSUVMRF9TSU5UMzJfNjcoNjcpLAogICAgICBGSUVMRF9TSU5UNjRfNjgoNjgpLAogICAgICBGSUVMREdST1VQNjkoNjkpLAogICAgICBURVNUT05FT0ZfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgVGVzdE9uZW9mQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RPbmVvZkNhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBUZXN0T25lb2ZDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDUzOiByZXR1cm4gRklFTERfRE9VQkxFXzUzOwogICAgICAgICAgY2FzZSA1NDogcmV0dXJuIEZJRUxEX0ZMT0FUXzU0OwogICAgICAgICAgY2FzZSA1NTogcmV0dXJuIEZJRUxEX0lOVDY0XzU1OwogICAgICAgICAgY2FzZSA1NjogcmV0dXJuIEZJRUxEX1VJTlQ2NF81NjsKICAgICAgICAgIGNhc2UgNTc6IHJldHVybiBGSUVMRF9JTlQzMl81NzsKICAgICAgICAgIGNhc2UgNTg6IHJldHVybiBGSUVMRF9GSVhFRDY0XzU4OwogICAgICAgICAgY2FzZSA1OTogcmV0dXJuIEZJRUxEX0ZJWEVEMzJfNTk7CiAgICAgICAgICBjYXNlIDYwOiByZXR1cm4gRklFTERfQk9PTF82MDsKICAgICAgICAgIGNhc2UgNjE6IHJldHVybiBGSUVMRF9TVFJJTkdfNjE7CiAgICAgICAgICBjYXNlIDYyOiByZXR1cm4gRklFTERfTUVTU0FHRV82MjsKICAgICAgICAgIGNhc2UgNjM6IHJldHVybiBGSUVMRF9CWVRFU182MzsKICAgICAgICAgIGNhc2UgNjQ6IHJldHVybiBGSUVMRF9VSU5UMzJfNjQ7CiAgICAgICAgICBjYXNlIDY1OiByZXR1cm4gRklFTERfU0ZJWEVEMzJfNjU7CiAgICAgICAgICBjYXNlIDY2OiByZXR1cm4gRklFTERfU0ZJWEVENjRfNjY7CiAgICAgICAgICBjYXNlIDY3OiByZXR1cm4gRklFTERfU0lOVDMyXzY3OwogICAgICAgICAgY2FzZSA2ODogcmV0dXJuIEZJRUxEX1NJTlQ2NF82ODsKICAgICAgICAgIGNhc2UgNjk6IHJldHVybiBGSUVMREdST1VQNjk7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBURVNUT05FT0ZfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgVGVzdE9uZW9mQ2FzZQogICAgZ2V0VGVzdE9uZW9mQ2FzZSgpIHsKICAgICAgcmV0dXJuIFRlc3RPbmVvZkNhc2UuZm9yTnVtYmVyKAogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGRvdWJsZSBmaWVsZERvdWJsZTFfID0gMEQ7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBmaWVsZF9kb3VibGVfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGUxKCkgewogICAgICByZXR1cm4gZmllbGREb3VibGUxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF8yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGZsb2F0IGZpZWxkRmxvYXQyXyA9IDBGOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGbG9hdDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0MigpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXQyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF8zX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGxvbmcgZmllbGRJbnQ2NDNfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQ2NDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDY0MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBmaWVsZF9pbnQ2NF8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDMoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0XzRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQ2NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0NCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNV9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMjVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1KCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMjVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkRml4ZWQ2NDZfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQ2NDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjQ2KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0Nl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl83X0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGludCBmaWVsZEZpeGVkMzI3XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQzMjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkMzI3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMjcoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzI3XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MXzhfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgYm9vbGVhbiBmaWVsZEJvb2w4XyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCb29sOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sOCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbDhfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NUUklOR185X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZFN0cmluZzlfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFN0cmluZzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nOSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGZpZWxkU3RyaW5nOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBmaWVsZFN0cmluZzlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUVTU0FHRV8xMF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkTWVzc2FnZTEwXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2UxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxME9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JZVEVTXzExX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQnl0ZXMxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXMxMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXMxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzMTEoKSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzMTFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl8xMl9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgaW50IGZpZWxkVWludDMyMTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzIxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDMyMTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyMTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzIxMigpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyMTJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fMTNfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIGludCBmaWVsZEVudW0xM18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRFbnVtMTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRW51bTEzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtMTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW0xMygpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRFbnVtMTNfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8gOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSID0gMTQ7CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkMzIxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzIxNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl8xNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzIxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyMTQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyMTRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0XzE1X0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ZpeGVkNjQxNV8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkNjQxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkNjQxNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDE1KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NDE1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UMzJfMTZfRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIGludCBmaWVsZFNpbnQzMjE2XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyMTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNpbnQzMjE2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMjE2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyMTYoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMjE2XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UNjRfMTdfRklFTERfTlVNQkVSID0gMTc7CiAgICBwcml2YXRlIGxvbmcgZmllbGRTaW50NjQxN18gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0MTcoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NDE3XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9ET1VCTEVfTElTVF8xOF9GSUVMRF9OVU1CRVIgPSAxODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgZmllbGREb3VibGVMaXN0MThfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0MThfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRG91YmxlTGlzdDE4Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGVMaXN0MTggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdDE4KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0MThfLmdldERvdWJsZShpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfTElTVF8xOV9GSUVMRF9OVU1CRVIgPSAxOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdDE5XyA9CiAgICAgICAgZW1wdHlGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3QxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRmxvYXRMaXN0MTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdDE5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0MTkoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdDE5Xy5nZXRGbG9hdChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfTElTVF8yMF9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkSW50NjRMaXN0MjBfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdDIwLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50NjRMaXN0MjBDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdDIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3QyMChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQ2NF9MSVNUXzIxX0ZJRUxEX05VTUJFUiA9IDIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRVaW50NjRMaXN0MjFfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3QyMV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0TGlzdDIxKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyX0xJU1RfMjJfRklFTERfTlVNQkVSID0gMjI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkSW50MzJMaXN0MjJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQzMkxpc3QyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0MjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0MjIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfTElTVF8yM19GSUVMRF9OVU1CRVIgPSAyMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkRml4ZWQ2NExpc3QyM18gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdDIzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NExpc3QyMyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM18uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl9MSVNUXzI0X0ZJRUxEX05VTUJFUiA9IDI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEZpeGVkMzJMaXN0MjRfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQzMkxpc3QyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdDI0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMkxpc3QyNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdDI0Xy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfTElTVF8yNV9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IGZpZWxkQm9vbExpc3QyNV8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3QyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkQm9vbExpc3QyNUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3QyNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbExpc3QyNShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3QyNV8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU1RSSU5HX0xJU1RfMjZfRklFTERfTlVNQkVSID0gMjY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRGaWVsZFN0cmluZ0xpc3QyNkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTdHJpbmdMaXN0MjZDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZ0xpc3QyNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nTGlzdDI2KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUVTU0FHRV9MSVNUXzI3X0ZJRUxEX05VTUJFUiA9IDI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNZXNzYWdlTGlzdDI3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JZVEVTX0xJU1RfMjhfRklFTERfTlVNQkVSID0gMjg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZEJ5dGVzTGlzdDI4XyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZ2V0RmllbGRCeXRlc0xpc3QyOExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCeXRlc0xpc3QyOC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEJ5dGVzTGlzdDI4Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlc0xpc3QyOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlc0xpc3QyOChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkQnl0ZXNMaXN0MjhfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDMyX0xJU1RfMjlfRklFTERfTlVNQkVSID0gMjk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdDI5XyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFVpbnQzMkxpc3QyOUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0MjkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjlDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdDI5Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjkoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9FTlVNX0xJU1RfMzBfRklFTERfTlVNQkVSID0gMzA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGZpZWxkRW51bUxpc3QzMF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZEVudW1MaXN0MzBfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0MzBMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPihmaWVsZEVudW1MaXN0MzBfLCBmaWVsZEVudW1MaXN0MzBfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0MzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8uY29udmVydChmaWVsZEVudW1MaXN0MzBfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyX0xJU1RfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkMzJMaXN0MzEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0X0xJU1RfMzJfRklFTERfTlVNQkVSID0gMzI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UMzJfTElTVF8zM19GSUVMRF9OVU1CRVIgPSAzMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0MzNfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdDMzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzMyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF9MSVNUXzM0X0ZJRUxEX05VTUJFUiA9IDM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTaW50NjRMaXN0MzRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50NjRMaXN0MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0MzQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdDM0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3QzNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdDM0KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUX1BBQ0tFRF8zNV9GSUVMRF9OVU1CRVIgPSAzNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmdldERvdWJsZShpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF9MSVNUX1BBQ0tFRF8zNl9GSUVMRF9OVU1CRVIgPSAzNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9CiAgICAgICAgZW1wdHlGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5nZXRGbG9hdChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0X0xJU1RfUEFDS0VEXzM3X0ZJRUxEX05VTUJFUiA9IDM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEludDY0TGlzdFBhY2tlZDM3TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQ2NF9MSVNUX1BBQ0tFRF8zOF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyX0xJU1RfUEFDS0VEXzM5X0ZJRUxEX05VTUJFUiA9IDM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzJMaXN0UGFja2VkMzlNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF9MSVNUX1BBQ0tFRF80MF9GSUVMRF9OVU1CRVIgPSA0MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl9MSVNUX1BBQ0tFRF80MV9GSUVMRF9OVU1CRVIgPSA0MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MX0xJU1RfUEFDS0VEXzQyX0ZJRUxEX05VTUJFUiA9IDQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0UGFja2VkNDIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkQm9vbExpc3RQYWNrZWQ0Mk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfTElTVF9QQUNLRURfNDNfRklFTERfTlVNQkVSID0gNDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fTElTVF9QQUNLRURfNDRfRklFTERfTlVNQkVSID0gNDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPihmaWVsZEVudW1MaXN0UGFja2VkNDRfLCBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8uY29udmVydChmaWVsZEVudW1MaXN0UGFja2VkNDRfLmdldChpbmRleCkpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRFbnVtTGlzdFBhY2tlZDQ0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl9MSVNUX1BBQ0tFRF80NV9GSUVMRF9OVU1CRVIgPSA0NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0X0xJU1RfUEFDS0VEXzQ2X0ZJRUxEX05VTUJFUiA9IDQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl9MSVNUX1BBQ0tFRF80N19GSUVMRF9OVU1CRVIgPSA0NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50MzJMaXN0UGFja2VkNDdNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0X0xJU1RfUEFDS0VEXzQ4X0ZJRUxEX05VTUJFUiA9IDQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50NjRMaXN0UGFja2VkNDhNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERHUk9VUDQ5X0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IGZpZWxkR3JvdXA0OV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkZ3JvdXA0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkR3JvdXA0OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRncm91cDQ5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSBnZXRGaWVsZEdyb3VwNDkoKSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5LmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRHcm91cDQ5XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDlPckJ1aWxkZXIgZ2V0RmllbGRHcm91cDQ5T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGRHcm91cDQ5XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkR3JvdXA0OV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERHUk9VUExJU1Q1MV9GSUVMRF9OVU1CRVIgPSA1MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MT4gZmllbGRHcm91cExpc3Q1MV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTE+IGdldEZpZWxkR3JvdXBMaXN0NTFMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRHcm91cExpc3Q1MV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEdyb3VwTGlzdDUxQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RmllbGRHcm91cExpc3Q1MShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIgZ2V0RmllbGRHcm91cExpc3Q1MU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFXzUzX0ZJRUxEX05VTUJFUiA9IDUzOwogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGREb3VibGU1MygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDUzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGU1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTUzKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTMpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Eb3VibGUpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBEOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUXzU0X0ZJRUxEX05VTUJFUiA9IDU0OwogICAgLyoqCiAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdDU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGbG9hdDU0KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDU0KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTQpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5GbG9hdCkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEY7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfNTVfRklFTERfTlVNQkVSID0gNTU7CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDY0NTUoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjQ1NSgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0XzU2X0ZJRUxEX05VTUJFUiA9IDU2OwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NDU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50NjQ1NigpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQ1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNTdfRklFTERfTlVNQkVSID0gNTc7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTcoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjU3KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfNThfRklFTERfTlVNQkVSID0gNTg7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDY0NTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU4OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0NTgoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBMOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVEMzJfNTlfRklFTERfTlVNQkVSID0gNTk7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDMyNTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU5OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MXzYwX0ZJRUxEX05VTUJFUiA9IDYwOwogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQm9vbDYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCb29sNjAoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbDYwKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Cb29sZWFuKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TVFJJTkdfNjFfRklFTERfTlVNQkVSID0gNjE7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZzYxKCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZzYxLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzYxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSAmJiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpKSB7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzYxLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmc2MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgICAgdGVzdE9uZW9mXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFXzYyX0ZJRUxEX05VTUJFUiA9IDYyOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlNjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTYyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWVzc2FnZTYyKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlNjJPckJ1aWxkZXIoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JZVEVTXzYzX0ZJRUxEX05VTUJFUiA9IDYzOwogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCeXRlczYzKCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlczYzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXM2MygpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYzKSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQzMjY0KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMjY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyNjQoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfNjVfRklFTERfTlVNQkVSID0gNjU7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDMyNjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDMyNjUoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMjY1KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0XzY2X0ZJRUxEX05VTUJFUiA9IDY2OwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDY2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQ2NDY2KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjY7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDY2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBMOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl82N19GSUVMRF9OVU1CRVIgPSA2NzsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50MzI2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDMyNjcoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzI2NygpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY3KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UNjRfNjhfRklFTERfTlVNQkVSID0gNjg7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDY0NjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNpbnQ2NDY4KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjg7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NDY4KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMREdST1VQNjlfRklFTERfTlVNQkVSID0gNjk7CiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkZ3JvdXA2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkR3JvdXA2OSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY5OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRncm91cDY5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBnZXRGaWVsZEdyb3VwNjkoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5T3JCdWlsZGVyIGdldEZpZWxkR3JvdXA2OU9yQnVpbGRlcigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9ET1VCTEVfNzFfRklFTERfTlVNQkVSID0gNzE7CiAgICBwcml2YXRlIGRvdWJsZSBmaWVsZFJlcXVpcmVkRG91YmxlNzFfID0gMEQ7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWREb3VibGU3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBkb3VibGUgZmllbGRfcmVxdWlyZWRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZERvdWJsZTcxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWREb3VibGU3MV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfRkxPQVRfNzJfRklFTERfTlVNQkVSID0gNzI7CiAgICBwcml2YXRlIGZsb2F0IGZpZWxkUmVxdWlyZWRGbG9hdDcyXyA9IDBGOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmbG9hdCBmaWVsZF9yZXF1aXJlZF9mbG9hdF83MiA9IDcyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEZsb2F0NzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmbG9hdCBmaWVsZF9yZXF1aXJlZF9mbG9hdF83MiA9IDcyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRGbG9hdDcyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRSZXF1aXJlZEZsb2F0NzIoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfSU5UNjRfNzNfRklFTERfTlVNQkVSID0gNzM7CiAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZEludDY0NzNfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDY0IGZpZWxkX3JlcXVpcmVkX2ludDY0XzczID0gNzM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkSW50NjQ3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDY0IGZpZWxkX3JlcXVpcmVkX2ludDY0XzczID0gNzM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEludDY0NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkUmVxdWlyZWRJbnQ2NDczKCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEludDY0NzNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX1VJTlQ2NF83NF9GSUVMRF9OVU1CRVIgPSA3NDsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFJlcXVpcmVkVWludDY0NzRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQ2NCBmaWVsZF9yZXF1aXJlZF91aW50NjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRVaW50NjQ3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50NjQgZmllbGRfcmVxdWlyZWRfdWludDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFVpbnQ2NDc0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkVWludDY0NzQoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkVWludDY0NzRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX0lOVDMyXzc1X0ZJRUxEX05VTUJFUiA9IDc1OwogICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZEludDMyNzVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgZmllbGRfcmVxdWlyZWRfaW50MzJfNzUgPSA3NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRJbnQzMjc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgZmllbGRfcmVxdWlyZWRfaW50MzJfNzUgPSA3NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkSW50MzI3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFJlcXVpcmVkSW50MzI3NSgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRJbnQzMjc1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9GSVhFRDY0Xzc2X0ZJRUxEX05VTUJFUiA9IDc2OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkNjQgZmllbGRfcmVxdWlyZWRfZml4ZWQ2NF83NiA9IDc2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEZpeGVkNjQ3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2ID0gNzY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX0ZJWEVEMzJfNzdfRklFTERfTlVNQkVSID0gNzc7CiAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgZmllbGRfcmVxdWlyZWRfZml4ZWQzMl83NyA9IDc3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEZpeGVkMzI3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9maXhlZDMyXzc3ID0gNzc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZpeGVkMzI3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEZpeGVkMzI3N187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfQk9PTF83OF9GSUVMRF9OVU1CRVIgPSA3ODsKICAgIHByaXZhdGUgYm9vbGVhbiBmaWVsZFJlcXVpcmVkQm9vbDc4XyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBib29sIGZpZWxkX3JlcXVpcmVkX2Jvb2xfNzggPSA3ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRCb29sNzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJvb2wgZmllbGRfcmVxdWlyZWRfYm9vbF83OCA9IDc4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRCb29sNzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkUmVxdWlyZWRCb29sNzgoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkQm9vbDc4XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9TVFJJTkdfNzlfRklFTERfTlVNQkVSID0gNzk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzkgPSA3OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTdHJpbmc3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFN0cmluZzc5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGRSZXF1aXJlZFN0cmluZzc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFJlcXVpcmVkU3RyaW5nNzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfTUVTU0FHRV84MF9GSUVMRF9OVU1CRVIgPSA4MDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9CWVRFU184MV9GSUVMRF9OVU1CRVIgPSA4MTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgZmllbGRfcmVxdWlyZWRfYnl0ZXNfODEgPSA4MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRCeXRlczgxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgZmllbGRfcmVxdWlyZWRfYnl0ZXNfODEgPSA4MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkQnl0ZXM4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRCeXRlczgxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9VSU5UMzJfODJfRklFTERfTlVNQkVSID0gODI7CiAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkVWludDMyODJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQzMjgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQzMiBmaWVsZF9yZXF1aXJlZF91aW50MzJfODIgPSA4Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkVWludDMyODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZFVpbnQzMjgyKCkgewogICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFVpbnQzMjgyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9FTlVNXzgzX0ZJRUxEX05VTUJFUiA9IDgzOwogICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZEVudW04M18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfcmVxdWlyZWRfZW51bV84MyA9IDgzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEVudW04MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEVudW04MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfcmVxdWlyZWRfZW51bV84MyA9IDgzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRFbnVtODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZFJlcXVpcmVkRW51bTgzKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZFJlcXVpcmVkRW51bTgzXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1JFUVVJUkVEX1NGSVhFRDMyXzg0X0ZJRUxEX05VTUJFUiA9IDg0OwogICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkMzIgZmllbGRfcmVxdWlyZWRfc2ZpeGVkMzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkMzIgZmllbGRfcmVxdWlyZWRfc2ZpeGVkMzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9SRVFVSVJFRF9TRklYRUQ2NF84NV9GSUVMRF9OVU1CRVIgPSA4NTsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkNjQgZmllbGRfcmVxdWlyZWRfc2ZpeGVkNjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkNjQgZmllbGRfcmVxdWlyZWRfc2ZpeGVkNjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfU0lOVDMyXzg2X0ZJRUxEX05VTUJFUiA9IDg2OwogICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQzMiBmaWVsZF9yZXF1aXJlZF9zaW50MzJfODYgPSA4Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTaW50MzI4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50MzIgZmllbGRfcmVxdWlyZWRfc2ludDMyXzg2ID0gODY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFNpbnQzMjg2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRTaW50MzI4NigpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTaW50MzI4Nl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfUkVRVUlSRURfU0lOVDY0Xzg3X0ZJRUxEX05VTUJFUiA9IDg3OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRTaW50NjQ4N18gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDY0IGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84NyA9IDg3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNpbnQ2NDg3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ludDY0ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkUmVxdWlyZWRTaW50NjQ4NygpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTaW50NjQ4N187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERSRVFVSVJFREdST1VQODhfRklFTERfTlVNQkVSID0gODg7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRyZXF1aXJlZGdyb3VwODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZHJlcXVpcmVkZ3JvdXA4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRHcm91cDg4XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4LmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRSZXF1aXJlZEdyb3VwODhfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkUmVxdWlyZWRHcm91cDg4XzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWREb3VibGU3MSgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkSW50NjQ3MygpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTaW50NjQ4NygpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTEwKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCk7IGkrKykgewogICAgICAgIGlmICghZ2V0RmllbGRNZXNzYWdlTGlzdDI3KGkpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTYyKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTYyKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxLCBmaWVsZERvdWJsZTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgyLCBmaWVsZEZsb2F0Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDMsIGZpZWxkSW50NjQzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDQsIGZpZWxkVWludDY0NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDUsIGZpZWxkSW50MzI1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg2LCBmaWVsZEZpeGVkNjQ2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMig3LCBmaWVsZEZpeGVkMzI3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg4LCBmaWVsZEJvb2w4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA5LCBmaWVsZFN0cmluZzlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCBnZXRGaWVsZE1lc3NhZ2UxMCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygxMSwgZmllbGRCeXRlczExXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDEyLCBmaWVsZFVpbnQzMjEyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxMywgZmllbGRFbnVtMTNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMigxNCwgZmllbGRTZml4ZWQzMjE0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTUsIGZpZWxkU2ZpeGVkNjQxNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMigxNiwgZmllbGRTaW50MzIxNl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgxNywgZmllbGRTaW50NjQxN18pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGREb3VibGVMaXN0MThfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDE4LCBmaWVsZERvdWJsZUxpc3QxOF8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRmxvYXRMaXN0MTlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTksIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0MjBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMjAsIGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDIxLCBmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIyLCBmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDY0TGlzdDIzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoMjMsIGZpZWxkRml4ZWQ2NExpc3QyM18uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMigyNCwgZmllbGRGaXhlZDMyTGlzdDI0Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCb29sTGlzdDI1Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMjUsIGZpZWxkQm9vbExpc3QyNV8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFN0cmluZ0xpc3QyNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI2LCBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI3LCBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEJ5dGVzTGlzdDI4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDI4LCBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0MjlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDI5LCBmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDMwLCBmaWVsZEVudW1MaXN0MzBfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDMxLCBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTZml4ZWQ2NExpc3QzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgzMiwgZmllbGRTZml4ZWQ2NExpc3QzMl8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoMzMsIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDM0LCBmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyODIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGVOb1RhZyhmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjkwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEZsb2F0TGlzdFBhY2tlZDM2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcoZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyOTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMwNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NE5vVGFnKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzE0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEludDMyTGlzdFBhY2tlZDM5TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcoZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyhmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkQm9vbExpc3RQYWNrZWQ0Mk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2xOb1RhZyhmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzU0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEVudW1MaXN0UGFja2VkNDRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM3OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRTaW50MzJMaXN0UGFja2VkNDdNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzg2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcoZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDQ5LCBnZXRGaWVsZEdyb3VwNDkoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEdyb3VwTGlzdDUxXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDUxLCBmaWVsZEdyb3VwTGlzdDUxXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgKICAgICAgICAgICAgNTMsIChkb3VibGUpKChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoCiAgICAgICAgICAgIDU0LCAoZmxvYXQpKChqYXZhLmxhbmcuRmxvYXQpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgKICAgICAgICAgICAgNTUsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoCiAgICAgICAgICAgIDU2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDU3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KAogICAgICAgICAgICA1OCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoCiAgICAgICAgICAgIDU5LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKAogICAgICAgICAgICA2MCwgKGJvb2xlYW4pKChqYXZhLmxhbmcuQm9vbGVhbikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNjEsIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNjIsIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKAogICAgICAgICAgICA2MywgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKAogICAgICAgICAgICA2NCwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoCiAgICAgICAgICAgIDY1LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjYpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgKICAgICAgICAgICAgNjYsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoCiAgICAgICAgICAgIDY3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoCiAgICAgICAgICAgIDY4LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoNjksIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5KSB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoNzEsIGZpZWxkUmVxdWlyZWREb3VibGU3MV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDcyLCBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDczLCBmaWVsZFJlcXVpcmVkSW50NjQ3M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg3NCwgZmllbGRSZXF1aXJlZFVpbnQ2NDc0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNzUsIGZpZWxkUmVxdWlyZWRJbnQzMjc1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg3NiwgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoNzcsIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDc4LCBmaWVsZFJlcXVpcmVkQm9vbDc4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA3OSwgZmllbGRSZXF1aXJlZFN0cmluZzc5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg4MCwgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcyg4MSwgZmllbGRSZXF1aXJlZEJ5dGVzODFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoODIsIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oODMsIGZpZWxkUmVxdWlyZWRFbnVtODNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMig4NCwgZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCg4NSwgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoODYsIGZpZWxkUmVxdWlyZWRTaW50MzI4Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCg4NywgZmllbGRSZXF1aXJlZFNpbnQ2NDg3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoODgsIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxLCBmaWVsZERvdWJsZTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDIsIGZpZWxkRmxvYXQyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgzLCBmaWVsZEludDY0M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDQsIGZpZWxkVWludDY0NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNSwgZmllbGRJbnQzMjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoNiwgZmllbGRGaXhlZDY0Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSg3LCBmaWVsZEZpeGVkMzI3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDgsIGZpZWxkQm9vbDhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDksIGZpZWxkU3RyaW5nOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZ2V0RmllbGRNZXNzYWdlMTAoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxMSwgZmllbGRCeXRlczExXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMTIsIGZpZWxkVWludDMyMTJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTMsIGZpZWxkRW51bTEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSgxNCwgZmllbGRTZml4ZWQzMjE0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgxNSwgZmllbGRTZml4ZWQ2NDE1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoMTYsIGZpZWxkU2ludDMyMTZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSgxNywgZmllbGRTaW50NjQxN18pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhmaWVsZEludDY0TGlzdDIwXy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjcsIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGkpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkQnl0ZXNMaXN0MjhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcoZmllbGRCeXRlc0xpc3QyOF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDMyTGlzdDI5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFVpbnQzMkxpc3QyOUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEVudW1MaXN0MzBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhmaWVsZEVudW1MaXN0MzBfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZmllbGRFbnVtTGlzdDMwXy5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdDM0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcoZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfWZpZWxkRW51bUxpc3RQYWNrZWQ0NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcoZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDQ5LCBnZXRGaWVsZEdyb3VwNDkoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEdyb3VwTGlzdDUxXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoNTEsIGZpZWxkR3JvdXBMaXN0NTFfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDUzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoCiAgICAgICAgICAgICAgNTMsIChkb3VibGUpKChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgKICAgICAgICAgICAgICA1NCwgKGZsb2F0KSgoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgKICAgICAgICAgICAgICA1NSwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKAogICAgICAgICAgICAgIDU2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgKICAgICAgICAgICAgICA1NywgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKAogICAgICAgICAgICAgIDU4LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKAogICAgICAgICAgICAgIDU5LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoCiAgICAgICAgICAgICAgNjAsIChib29sZWFuKSgoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDYxLCB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjIsIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoCiAgICAgICAgICAgICAgNjMsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKAogICAgICAgICAgICAgIDY0LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkMzJTaXplKAogICAgICAgICAgICAgIDY1LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjYpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkNjRTaXplKAogICAgICAgICAgICAgIDY2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY3KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoCiAgICAgICAgICAgICAgNjcsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplKAogICAgICAgICAgICAgIDY4LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSg2OSwgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkpIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDcxLCBmaWVsZFJlcXVpcmVkRG91YmxlNzFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDcyLCBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoNzMsIGZpZWxkUmVxdWlyZWRJbnQ2NDczXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemUoNzQsIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNzUsIGZpZWxkUmVxdWlyZWRJbnQzMjc1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKDc2LCBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKDc3LCBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDc4LCBmaWVsZFJlcXVpcmVkQm9vbDc4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg3OSwgZmllbGRSZXF1aXJlZFN0cmluZzc5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgwLCBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoODEsIGZpZWxkUmVxdWlyZWRCeXRlczgxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoODIsIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSg4MywgZmllbGRSZXF1aXJlZEVudW04M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoODQsIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSg4NSwgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZSg4NiwgZmllbGRSZXF1aXJlZFNpbnQzMjg2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoODcsIGZpZWxkUmVxdWlyZWRTaW50NjQ4N18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoODgsIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgb2JqOwoKICAgICAgaWYgKGhhc0ZpZWxkRG91YmxlMSgpICE9IG90aGVyLmhhc0ZpZWxkRG91YmxlMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZERvdWJsZTEoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGREb3VibGUxKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkRG91YmxlMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEZsb2F0MigpICE9IG90aGVyLmhhc0ZpZWxkRmxvYXQyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkRmxvYXQyKCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldEZpZWxkRmxvYXQyKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkRmxvYXQyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkSW50NjQzKCkgIT0gb3RoZXIuaGFzRmllbGRJbnQ2NDMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRJbnQ2NDMoKSkgewogICAgICAgIGlmIChnZXRGaWVsZEludDY0MygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50NjQzKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRVaW50NjQ0KCkgIT0gb3RoZXIuaGFzRmllbGRVaW50NjQ0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkVWludDY0NCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkVWludDY0NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDY0NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1KCkgIT0gb3RoZXIuaGFzRmllbGRJbnQzMjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRJbnQzMjUoKSkgewogICAgICAgIGlmIChnZXRGaWVsZEludDMyNSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRGaXhlZDY0NigpICE9IG90aGVyLmhhc0ZpZWxkRml4ZWQ2NDYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRGaXhlZDY0NigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NDYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkNjQ2KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRGaXhlZDMyNygpICE9IG90aGVyLmhhc0ZpZWxkRml4ZWQzMjcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRGaXhlZDMyNygpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQzMjcoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRCb29sOCgpICE9IG90aGVyLmhhc0ZpZWxkQm9vbDgoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRCb29sOCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkQm9vbDgoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEJvb2w4KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTdHJpbmc5KCkgIT0gb3RoZXIuaGFzRmllbGRTdHJpbmc5KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkU3RyaW5nOSgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZFN0cmluZzkoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2UxMCgpICE9IG90aGVyLmhhc0ZpZWxkTWVzc2FnZTEwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTEwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2UxMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEJ5dGVzMTEoKSAhPSBvdGhlci5oYXNGaWVsZEJ5dGVzMTEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRCeXRlczExKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkQnl0ZXMxMSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlczExKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkVWludDMyMTIoKSAhPSBvdGhlci5oYXNGaWVsZFVpbnQzMjEyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkVWludDMyMTIoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFVpbnQzMjEyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRVaW50MzIxMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRW51bTEzKCkgIT0gb3RoZXIuaGFzRmllbGRFbnVtMTMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRFbnVtMTMoKSkgewogICAgICAgIGlmIChmaWVsZEVudW0xM18gIT0gb3RoZXIuZmllbGRFbnVtMTNfKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU2ZpeGVkMzIxNCgpICE9IG90aGVyLmhhc0ZpZWxkU2ZpeGVkMzIxNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFNmaXhlZDMyMTQoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyMTQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFNmaXhlZDMyMTQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNmaXhlZDY0MTUoKSAhPSBvdGhlci5oYXNGaWVsZFNmaXhlZDY0MTUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRTZml4ZWQ2NDE1KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRTZml4ZWQ2NDE1KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDE1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTaW50MzIxNigpICE9IG90aGVyLmhhc0ZpZWxkU2ludDMyMTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRTaW50MzIxNigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkU2ludDMyMTYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFNpbnQzMjE2KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTaW50NjQxNygpICE9IG90aGVyLmhhc0ZpZWxkU2ludDY0MTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRTaW50NjQxNygpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkU2ludDY0MTcoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFNpbnQ2NDE3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRCeXRlc0xpc3QyOExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWZpZWxkRW51bUxpc3QzMF8uZXF1YWxzKG90aGVyLmZpZWxkRW51bUxpc3QzMF8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFmaWVsZEVudW1MaXN0UGFja2VkNDRfLmVxdWFscyhvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEdyb3VwNDkoKSAhPSBvdGhlci5oYXNGaWVsZEdyb3VwNDkoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRHcm91cDQ5KCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkR3JvdXA0OSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRHcm91cDQ5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRGaWVsZEdyb3VwTGlzdDUxTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkR3JvdXBMaXN0NTFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZERvdWJsZTcxKCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEZsb2F0NzIoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkSW50NjQ3MygpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRSZXF1aXJlZEludDY0NzMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkSW50NjQ3MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkVWludDY0NzQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkVWludDY0NzQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRJbnQzMjc1KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRSZXF1aXJlZEludDMyNzUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkSW50MzI3NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRSZXF1aXJlZEZpeGVkMzI3NygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkQm9vbDc4KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRSZXF1aXJlZEJvb2w3OCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRSZXF1aXJlZFN0cmluZzc5KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRSZXF1aXJlZEJ5dGVzODEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkUmVxdWlyZWRCeXRlczgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRVaW50MzI4MigpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRVaW50MzI4MigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkVWludDMyODIoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkVWludDMyODIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkVWludDMyODIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkgIT0gb3RoZXIuaGFzRmllbGRSZXF1aXJlZEVudW04MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEVudW04M18gIT0gb3RoZXIuZmllbGRSZXF1aXJlZEVudW04M18pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpICE9IG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ludDMyODYoKSkgewogICAgICAgIGlmIChnZXRGaWVsZFJlcXVpcmVkU2ludDMyODYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFJlcXVpcmVkU2ludDMyODYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEdyb3VwODgoKSAhPSBvdGhlci5oYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEdyb3VwODgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFRlc3RPbmVvZkNhc2UoKS5lcXVhbHMob3RoZXIuZ2V0VGVzdE9uZW9mQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKHRlc3RPbmVvZkNhc2VfKSB7CiAgICAgICAgY2FzZSA1MzoKICAgICAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGREb3VibGU1MygpKQogICAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgICAgb3RoZXIuZ2V0RmllbGREb3VibGU1MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NDoKICAgICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmllbGRGbG9hdDU0KCkpCiAgICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZEZsb2F0NTQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTU6CiAgICAgICAgICBpZiAoZ2V0RmllbGRJbnQ2NDU1KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEludDY0NTUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NjoKICAgICAgICAgIGlmIChnZXRGaWVsZFVpbnQ2NDU2KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFVpbnQ2NDU2KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTc6CiAgICAgICAgICBpZiAoZ2V0RmllbGRJbnQzMjU3KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEludDMyNTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1ODoKICAgICAgICAgIGlmIChnZXRGaWVsZEZpeGVkNjQ1OCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRGaXhlZDY0NTgoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1OToKICAgICAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzI1OSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRGaXhlZDMyNTkoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MDoKICAgICAgICAgIGlmIChnZXRGaWVsZEJvb2w2MCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRCb29sNjAoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MToKICAgICAgICAgIGlmICghZ2V0RmllbGRTdHJpbmc2MSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFN0cmluZzYxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYyOgogICAgICAgICAgaWYgKCFnZXRGaWVsZE1lc3NhZ2U2MigpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2U2MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MzoKICAgICAgICAgIGlmICghZ2V0RmllbGRCeXRlczYzKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkQnl0ZXM2MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NDoKICAgICAgICAgIGlmIChnZXRGaWVsZFVpbnQzMjY0KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFVpbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjU6CiAgICAgICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMjY1KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFNmaXhlZDMyNjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NjoKICAgICAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0NjYoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkNjQ2NigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY3OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ludDMyNjcoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDMyNjcoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2ODoKICAgICAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NDY4KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZFNpbnQ2NDY4KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjk6CiAgICAgICAgICBpZiAoIWdldEZpZWxkR3JvdXA2OSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEdyb3VwNjkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZpZWxkRG91YmxlMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRE9VQkxFXzFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTEoKSkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEZsb2F0MigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRkxPQVRfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXRGaWVsZEZsb2F0MigpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRJbnQ2NDMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0XzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkSW50NjQzKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFVpbnQ2NDQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFVpbnQ2NDQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl81X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEZpeGVkNjQ2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDY0XzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkRml4ZWQ2NDYoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRml4ZWQzMjcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyNygpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEJvb2w4KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MXzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldEZpZWxkQm9vbDgoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU3RyaW5nOSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HXzlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU3RyaW5nOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NRVNTQUdFXzEwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE1lc3NhZ2UxMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkQnl0ZXMxMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfQllURVNfMTFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXMxMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkVWludDMyMTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQzMl8xMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50MzIxMigpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEVudW0xMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRU5VTV8xM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZmllbGRFbnVtMTNfOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNmaXhlZDMyMTQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDMyXzE0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyMTQoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTZml4ZWQ2NDE1KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF8xNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NDE1KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFNpbnQzMjE2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfMTZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ludDMyMTYoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRTaW50NjQxNygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0lOVDY0XzE3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFNpbnQ2NDE3KCkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZERvdWJsZUxpc3QxOENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRE9VQkxFX0xJU1RfMThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRmxvYXRMaXN0MTlDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZMT0FUX0xJU1RfMTlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQ2NExpc3QyMENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UNjRfTElTVF8yMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQ2NExpc3QyMExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQ2NExpc3QyMUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDY0X0xJU1RfMjFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkSW50MzJMaXN0MjJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyX0xJU1RfMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDY0X0xJU1RfMjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzJMaXN0MjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfTElTVF8yNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkQm9vbExpc3QyNUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfQk9PTF9MSVNUXzI1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTdHJpbmdMaXN0MjZDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NUUklOR19MSVNUXzI2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFN0cmluZ0xpc3QyNkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZE1lc3NhZ2VMaXN0MjdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfTElTVF8yN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkQnl0ZXNMaXN0MjhDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JZVEVTX0xJU1RfMjhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50MzJMaXN0MjlDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQzMl9MSVNUXzI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQzMkxpc3QyOUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEVudW1MaXN0MzBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0VOVU1fTElTVF8zMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZmllbGRFbnVtTGlzdDMwXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyTGlzdDMxQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQzMl9MSVNUXzMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NGSVhFRDY0X0xJU1RfMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50MzJMaXN0MzNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQzMl9MSVNUXzMzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NExpc3QzNENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0lOVDY0X0xJU1RfMzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9ET1VCTEVfTElTVF9QQUNLRURfMzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZMT0FUX0xJU1RfUEFDS0VEXzM2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0X0xJU1RfUEFDS0VEXzM3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UNjRfTElTVF9QQUNLRURfMzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyX0xJU1RfUEFDS0VEXzM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQ2NF9MSVNUX1BBQ0tFRF80MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQzMl9MSVNUX1BBQ0tFRF80MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfQk9PTF9MSVNUX1BBQ0tFRF80Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UMzJfTElTVF9QQUNLRURfNDNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRU5VTV9MSVNUX1BBQ0tFRF80NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQzMl9MSVNUX1BBQ0tFRF80NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF9MSVNUX1BBQ0tFRF80Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0lOVDMyX0xJU1RfUEFDS0VEXzQ3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0lOVDY0X0xJU1RfUEFDS0VEXzQ4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEdyb3VwNDkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxER1JPVVA0OV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRHcm91cDQ5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRHcm91cExpc3Q1MUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERHUk9VUExJU1Q1MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRHcm91cExpc3Q1MUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0RPVUJMRV83MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9GTE9BVF83Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0lOVDY0XzczX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkSW50NjQ3MygpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9VSU5UNjRfNzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEludDMyNzUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0lOVDMyXzc1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkSW50MzI3NSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9GSVhFRDY0Xzc2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9GSVhFRDMyXzc3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0JPT0xfNzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRCb29sNzgoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfU1RSSU5HXzc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9NRVNTQUdFXzgwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEJ5dGVzODEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX0JZVEVTXzgxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRVaW50MzI4MigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfVUlOVDMyXzgyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFJlcXVpcmVkVWludDMyODIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZEVudW04MygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfUkVRVUlSRURfRU5VTV84M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZmllbGRSZXF1aXJlZEVudW04M187CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9TRklYRUQzMl84NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDMyODQoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX1NGSVhFRDY0Xzg1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NSgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRSZXF1aXJlZFNpbnQzMjg2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9SRVFVSVJFRF9TSU5UMzJfODZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRTaW50MzI4NigpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1JFUVVJUkVEX1NJTlQ2NF84N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERSRVFVSVJFREdST1VQODhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKHRlc3RPbmVvZkNhc2VfKSB7CiAgICAgICAgY2FzZSA1MzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0RPVUJMRV81M19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTUzKCkpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF81NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgZ2V0RmllbGRGbG9hdDU0KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0XzU1X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRJbnQ2NDU1KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF81Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkVWludDY0NTYoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU3OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfNTdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMjU3KCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQ2NF81OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkRml4ZWQ2NDU4KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1OToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyNTkoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjA6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MXzYwX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgICAgZ2V0RmllbGRCb29sNjAoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HXzYxX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU3RyaW5nNjEoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfNjJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRNZXNzYWdlNjIoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JZVEVTXzYzX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXM2MygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyXzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyNjQoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjU6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQzMl82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyNjUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjY6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF82Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkU2ZpeGVkNjQ2NigpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzI2NygpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2ODoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkU2ludDY0NjgoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY5OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERHUk9VUDY5X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkR3JvdXA2OSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldEZpZWxkR3JvdXA0OUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRHcm91cExpc3Q1MUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMV8gPSAwOwogICAgICAgIGJpdEZpZWxkMl8gPSAwOwogICAgICAgIGZpZWxkRG91YmxlMV8gPSAwRDsKICAgICAgICBmaWVsZEZsb2F0Ml8gPSAwRjsKICAgICAgICBmaWVsZEludDY0M18gPSAwTDsKICAgICAgICBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAgICAgZmllbGRJbnQzMjVfID0gMDsKICAgICAgICBmaWVsZEZpeGVkNjQ2XyA9IDBMOwogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gMDsKICAgICAgICBmaWVsZEJvb2w4XyA9IGZhbHNlOwogICAgICAgIGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgZmllbGRVaW50MzIxMl8gPSAwOwogICAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IDA7CiAgICAgICAgZmllbGRTZml4ZWQ2NDE1XyA9IDBMOwogICAgICAgIGZpZWxkU2ludDMyMTZfID0gMDsKICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBmaWVsZEludDY0TGlzdDIwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG51bGw7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdDM0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZEdyb3VwNDlfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRHcm91cDQ5QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRHcm91cDQ5QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRHcm91cDQ5QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXyA9IG51bGw7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkR3JvdXA2OUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkR3JvdXA2OUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGZpZWxkUmVxdWlyZWREb3VibGU3MV8gPSAwRDsKICAgICAgICBmaWVsZFJlcXVpcmVkRmxvYXQ3Ml8gPSAwRjsKICAgICAgICBmaWVsZFJlcXVpcmVkSW50NjQ3M18gPSAwTDsKICAgICAgICBmaWVsZFJlcXVpcmVkVWludDY0NzRfID0gMEw7CiAgICAgICAgZmllbGRSZXF1aXJlZEludDMyNzVfID0gMDsKICAgICAgICBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2XyA9IDBMOwogICAgICAgIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfID0gMDsKICAgICAgICBmaWVsZFJlcXVpcmVkQm9vbDc4XyA9IGZhbHNlOwogICAgICAgIGZpZWxkUmVxdWlyZWRTdHJpbmc3OV8gPSAiIjsKICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZmllbGRSZXF1aXJlZEJ5dGVzODFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAgIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8gPSAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRFbnVtODNfID0gMDsKICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NF8gPSAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1XyA9IDBMOwogICAgICAgIGZpZWxkUmVxdWlyZWRTaW50MzI4Nl8gPSAwOwogICAgICAgIGZpZWxkUmVxdWlyZWRTaW50NjQ4N18gPSAwTDsKICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMV8gIT0gMCkgeyBidWlsZFBhcnRpYWwxKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDIocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHJlc3VsdCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuZmllbGRNZXNzYWdlTGlzdDI3XyA9IGZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1lc3NhZ2VMaXN0MjdfID0gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRFbnVtTGlzdDMwXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5maWVsZEVudW1MaXN0MzBfID0gZmllbGRFbnVtTGlzdDMwXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBmaWVsZEVudW1MaXN0UGFja2VkNDRfOwogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuZmllbGRHcm91cExpc3Q1MV8gPSBmaWVsZEdyb3VwTGlzdDUxXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LmZpZWxkR3JvdXBMaXN0NTFfID0gZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGREb3VibGUxXyA9IGZpZWxkRG91YmxlMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRGbG9hdDJfID0gZmllbGRGbG9hdDJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50NjQzXyA9IGZpZWxkSW50NjQzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQ2NDRfID0gZmllbGRVaW50NjQ0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyNV8gPSBmaWVsZEludDMyNV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDY0Nl8gPSBmaWVsZEZpeGVkNjQ2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkMzI3XyA9IGZpZWxkRml4ZWQzMjdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkQm9vbDhfID0gZmllbGRCb29sOF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRTdHJpbmc5XyA9IGZpZWxkU3RyaW5nOV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNZXNzYWdlMTBfID0gZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmaWVsZE1lc3NhZ2UxMF8KICAgICAgICAgICAgICA6IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEJ5dGVzMTFfID0gZmllbGRCeXRlczExXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQzMjEyXyA9IGZpZWxkVWludDMyMTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRW51bTEzXyA9IGZpZWxkRW51bTEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDMyMTRfID0gZmllbGRTZml4ZWQzMjE0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDY0MTVfID0gZmllbGRTZml4ZWQ2NDE1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQzMjE2XyA9IGZpZWxkU2ludDMyMTZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDY0MTdfID0gZmllbGRTaW50NjQxN187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRG91YmxlTGlzdDE4XyA9IGZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZsb2F0TGlzdDE5XyA9IGZpZWxkRmxvYXRMaXN0MTlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkSW50NjRMaXN0MjBfID0gZmllbGRJbnQ2NExpc3QyMF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDY0TGlzdDIxXyA9IGZpZWxkVWludDY0TGlzdDIxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyTGlzdDIyXyA9IGZpZWxkSW50MzJMaXN0MjJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDY0TGlzdDIzXyA9IGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkMzJMaXN0MjRfID0gZmllbGRGaXhlZDMyTGlzdDI0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkQm9vbExpc3QyNV8gPSBmaWVsZEJvb2xMaXN0MjVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFN0cmluZ0xpc3QyNl8gPSBmaWVsZFN0cmluZ0xpc3QyNl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRCeXRlc0xpc3QyOF8gPSBmaWVsZEJ5dGVzTGlzdDI4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50MzJMaXN0MjlfID0gZmllbGRVaW50MzJMaXN0MjlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMV8gPSBiaXRGaWVsZDFfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDMyTGlzdDMzXyA9IGZpZWxkU2ludDMyTGlzdDMzXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50NjRMaXN0MzRfID0gZmllbGRTaW50NjRMaXN0MzRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBmaWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEJvb2xMaXN0UGFja2VkNDJfID0gZmllbGRCb29sTGlzdFBhY2tlZDQyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZmllbGRTaW50MzJMaXN0UGFja2VkNDdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF87CiAgICAgICAgfQogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkR3JvdXA0OV8gPSBmaWVsZEdyb3VwNDlCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmaWVsZEdyb3VwNDlfCiAgICAgICAgICAgICAgOiBmaWVsZEdyb3VwNDlCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyXyA9IGJpdEZpZWxkMl87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZERvdWJsZTcxXyA9IGZpZWxkUmVxdWlyZWREb3VibGU3MV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZEZsb2F0NzJfID0gZmllbGRSZXF1aXJlZEZsb2F0NzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRJbnQ2NDczXyA9IGZpZWxkUmVxdWlyZWRJbnQ2NDczXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkVWludDY0NzRfID0gZmllbGRSZXF1aXJlZFVpbnQ2NDc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkSW50MzI3NV8gPSBmaWVsZFJlcXVpcmVkSW50MzI3NV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gPSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkRml4ZWQzMjc3XyA9IGZpZWxkUmVxdWlyZWRGaXhlZDMyNzdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRCb29sNzhfID0gZmllbGRSZXF1aXJlZEJvb2w3OF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IGZpZWxkUmVxdWlyZWRTdHJpbmc3OV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8KICAgICAgICAgICAgICA6IGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRCeXRlczgxXyA9IGZpZWxkUmVxdWlyZWRCeXRlczgxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkVWludDMyODJfID0gZmllbGRSZXF1aXJlZFVpbnQzMjgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFJlcXVpcmVkRW51bTgzXyA9IGZpZWxkUmVxdWlyZWRFbnVtODNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XyA9IGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfID0gZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRTaW50MzI4Nl8gPSBmaWVsZFJlcXVpcmVkU2ludDMyODZfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRTaW50NjQ4N18gPSBmaWVsZFJlcXVpcmVkU2ludDY0ODdfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkUmVxdWlyZWRHcm91cDg4XyA9IGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRSZXF1aXJlZEdyb3VwODhfCiAgICAgICAgICAgICAgOiBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMV8gfD0gdG9fYml0RmllbGQxXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0LnRlc3RPbmVvZkNhc2VfID0gdGVzdE9uZW9mQ2FzZV87CiAgICAgICAgcmVzdWx0LnRlc3RPbmVvZl8gPSB0aGlzLnRlc3RPbmVvZl87CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyICYmCiAgICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LnRlc3RPbmVvZl8gPSBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSAmJgogICAgICAgICAgICBmaWVsZEdyb3VwNjlCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQudGVzdE9uZW9mXyA9IGZpZWxkR3JvdXA2OUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkRG91YmxlMSgpKSB7CiAgICAgICAgICBzZXRGaWVsZERvdWJsZTEob3RoZXIuZ2V0RmllbGREb3VibGUxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRGbG9hdDIoKSkgewogICAgICAgICAgc2V0RmllbGRGbG9hdDIob3RoZXIuZ2V0RmllbGRGbG9hdDIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEludDY0MygpKSB7CiAgICAgICAgICBzZXRGaWVsZEludDY0MyhvdGhlci5nZXRGaWVsZEludDY0MygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkVWludDY0NCgpKSB7CiAgICAgICAgICBzZXRGaWVsZFVpbnQ2NDQob3RoZXIuZ2V0RmllbGRVaW50NjQ0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRJbnQzMjUoKSkgewogICAgICAgICAgc2V0RmllbGRJbnQzMjUob3RoZXIuZ2V0RmllbGRJbnQzMjUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEZpeGVkNjQ2KCkpIHsKICAgICAgICAgIHNldEZpZWxkRml4ZWQ2NDYob3RoZXIuZ2V0RmllbGRGaXhlZDY0NigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkRml4ZWQzMjcoKSkgewogICAgICAgICAgc2V0RmllbGRGaXhlZDMyNyhvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRCb29sOCgpKSB7CiAgICAgICAgICBzZXRGaWVsZEJvb2w4KG90aGVyLmdldEZpZWxkQm9vbDgoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFN0cmluZzkoKSkgewogICAgICAgICAgZmllbGRTdHJpbmc5XyA9IG90aGVyLmZpZWxkU3RyaW5nOV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICAgIG1lcmdlRmllbGRNZXNzYWdlMTAob3RoZXIuZ2V0RmllbGRNZXNzYWdlMTAoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEJ5dGVzMTEoKSkgewogICAgICAgICAgc2V0RmllbGRCeXRlczExKG90aGVyLmdldEZpZWxkQnl0ZXMxMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkVWludDMyMTIoKSkgewogICAgICAgICAgc2V0RmllbGRVaW50MzIxMihvdGhlci5nZXRGaWVsZFVpbnQzMjEyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRFbnVtMTMoKSkgewogICAgICAgICAgc2V0RmllbGRFbnVtMTMob3RoZXIuZ2V0RmllbGRFbnVtMTMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFNmaXhlZDMyMTQoKSkgewogICAgICAgICAgc2V0RmllbGRTZml4ZWQzMjE0KG90aGVyLmdldEZpZWxkU2ZpeGVkMzIxNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkU2ZpeGVkNjQxNSgpKSB7CiAgICAgICAgICBzZXRGaWVsZFNmaXhlZDY0MTUob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDE1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRTaW50MzIxNigpKSB7CiAgICAgICAgICBzZXRGaWVsZFNpbnQzMjE2KG90aGVyLmdldEZpZWxkU2ludDMyMTYoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFNpbnQ2NDE3KCkpIHsKICAgICAgICAgIHNldEZpZWxkU2ludDY0MTcob3RoZXIuZ2V0RmllbGRTaW50NjQxNygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZERvdWJsZUxpc3QxOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGREb3VibGVMaXN0MThfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8gPSBvdGhlci5maWVsZERvdWJsZUxpc3QxOF87CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5hZGRBbGwob3RoZXIuZmllbGREb3VibGVMaXN0MThfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRmxvYXRMaXN0MTlfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRmxvYXRMaXN0MTlfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5XyA9IG90aGVyLmZpZWxkRmxvYXRMaXN0MTlfOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRGbG9hdExpc3QxOV8uYWRkQWxsKG90aGVyLmZpZWxkRmxvYXRMaXN0MTlfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkSW50NjRMaXN0MjBfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkSW50NjRMaXN0MjBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXyA9IG90aGVyLmZpZWxkSW50NjRMaXN0MjBfOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0MjBJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uYWRkQWxsKG90aGVyLmZpZWxkSW50NjRMaXN0MjBfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkVWludDY0TGlzdDIxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFVpbnQ2NExpc3QyMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IG90aGVyLmZpZWxkVWludDY0TGlzdDIxXzsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZEFsbChvdGhlci5maWVsZFVpbnQ2NExpc3QyMV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQzMkxpc3QyMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQzMkxpc3QyMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfID0gb3RoZXIuZmllbGRJbnQzMkxpc3QyMl87CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3QyMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5hZGRBbGwob3RoZXIuZmllbGRJbnQzMkxpc3QyMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDY0TGlzdDIzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkNjRMaXN0MjNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gb3RoZXIuZmllbGRGaXhlZDY0TGlzdDIzXzsKICAgICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRml4ZWQzMkxpc3QyNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGaXhlZDMyTGlzdDI0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IG90aGVyLmZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRBbGwob3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEJvb2xMaXN0MjVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkQm9vbExpc3QyNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8gPSBvdGhlci5maWVsZEJvb2xMaXN0MjVfOwogICAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQWxsKG90aGVyLmZpZWxkQm9vbExpc3QyNV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTdHJpbmdMaXN0MjZfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU3RyaW5nTGlzdDI2Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0gb3RoZXIuZmllbGRTdHJpbmdMaXN0MjZfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8uYWRkQWxsKG90aGVyLmZpZWxkU3RyaW5nTGlzdDI2Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG90aGVyLmZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkQWxsKG90aGVyLmZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLmZpZWxkTWVzc2FnZUxpc3QyN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEJ5dGVzTGlzdDI4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEJ5dGVzTGlzdDI4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBvdGhlci5maWVsZEJ5dGVzTGlzdDI4XzsKICAgICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJ5dGVzTGlzdDI4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLmFkZEFsbChvdGhlci5maWVsZEJ5dGVzTGlzdDI4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFVpbnQzMkxpc3QyOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRVaW50MzJMaXN0MjlfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBvdGhlci5maWVsZFVpbnQzMkxpc3QyOV87CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5hZGRBbGwob3RoZXIuZmllbGRVaW50MzJMaXN0MjlfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRW51bUxpc3QzMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRFbnVtTGlzdDMwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IG90aGVyLmZpZWxkRW51bUxpc3QzMF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZEFsbChvdGhlci5maWVsZEVudW1MaXN0MzBfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0MzFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0MzFfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0MzFJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0MzFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0MzJfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ludDMyTGlzdDMzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNpbnQzMkxpc3QzM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IG90aGVyLmZpZWxkU2ludDMyTGlzdDMzXzsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLmFkZEFsbChvdGhlci5maWVsZFNpbnQzMkxpc3QzM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50NjRMaXN0MzRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDY0TGlzdDM0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gb3RoZXIuZmllbGRTaW50NjRMaXN0MzRfOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uYWRkQWxsKG90aGVyLmZpZWxkU2ludDY0TGlzdDM0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBvdGhlci5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV87CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5hZGRBbGwob3RoZXIuZmllbGREb3VibGVMaXN0UGFja2VkMzVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IG90aGVyLmZpZWxkRmxvYXRMaXN0UGFja2VkMzZfOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uYWRkQWxsKG90aGVyLmZpZWxkRmxvYXRMaXN0UGFja2VkMzZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IG90aGVyLmZpZWxkSW50NjRMaXN0UGFja2VkMzdfOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uYWRkQWxsKG90aGVyLmZpZWxkSW50NjRMaXN0UGFja2VkMzdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IG90aGVyLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4XzsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmFkZEFsbChvdGhlci5maWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gb3RoZXIuZmllbGRJbnQzMkxpc3RQYWNrZWQzOV87CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5hZGRBbGwob3RoZXIuZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gb3RoZXIuZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXzsKICAgICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IG90aGVyLmZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV87CiAgICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRBbGwob3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEJvb2xMaXN0UGFja2VkNDJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBvdGhlci5maWVsZEJvb2xMaXN0UGFja2VkNDJfOwogICAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uYWRkQWxsKG90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gb3RoZXIuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfOwogICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uYWRkQWxsKG90aGVyLmZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5hZGRBbGwob3RoZXIuZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8gPSBvdGhlci5maWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmFkZEFsbChvdGhlci5maWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBvdGhlci5maWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmFkZEFsbChvdGhlci5maWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBvdGhlci5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0N187CiAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5hZGRBbGwob3RoZXIuZmllbGRTaW50MzJMaXN0UGFja2VkNDdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XyA9IG90aGVyLmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmFkZEFsbChvdGhlci5maWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEdyb3VwNDkoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZEdyb3VwNDkob3RoZXIuZ2V0RmllbGRHcm91cDQ5KCkpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIuZmllbGRHcm91cExpc3Q1MV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXyA9IG90aGVyLmZpZWxkR3JvdXBMaXN0NTFfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uYWRkQWxsKG90aGVyLmZpZWxkR3JvdXBMaXN0NTFfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5maWVsZEdyb3VwTGlzdDUxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8gPSBvdGhlci5maWVsZEdyb3VwTGlzdDUxXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmZpZWxkR3JvdXBMaXN0NTFfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZERvdWJsZTcxKCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWREb3VibGU3MShvdGhlci5nZXRGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MihvdGhlci5nZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRJbnQ2NDczKG90aGVyLmdldEZpZWxkUmVxdWlyZWRJbnQ2NDczKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRVaW50NjQ3NChvdGhlci5nZXRGaWVsZFJlcXVpcmVkVWludDY0NzQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkSW50MzI3NShvdGhlci5nZXRGaWVsZFJlcXVpcmVkSW50MzI3NSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRGaXhlZDY0NzYoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZEZpeGVkNjQ3NihvdGhlci5nZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KG90aGVyLmdldEZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkQm9vbDc4KCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRCb29sNzgob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEJvb2w3OCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gb3RoZXIuZmllbGRSZXF1aXJlZFN0cmluZzc5XzsKICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkUmVxdWlyZWRNZXNzYWdlODAob3RoZXIuZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRCeXRlczgxKG90aGVyLmdldEZpZWxkUmVxdWlyZWRCeXRlczgxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRVaW50MzI4MihvdGhlci5nZXRGaWVsZFJlcXVpcmVkVWludDMyODIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRFbnVtODMob3RoZXIuZ2V0RmllbGRSZXF1aXJlZEVudW04MygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpIHsKICAgICAgICAgIHNldEZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KG90aGVyLmdldEZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZFNmaXhlZDY0ODUob3RoZXIuZ2V0RmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFJlcXVpcmVkU2ludDMyODYoKSkgewogICAgICAgICAgc2V0RmllbGRSZXF1aXJlZFNpbnQzMjg2KG90aGVyLmdldEZpZWxkUmVxdWlyZWRTaW50MzI4NigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkUmVxdWlyZWRTaW50NjQ4NygpKSB7CiAgICAgICAgICBzZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcob3RoZXIuZ2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRSZXF1aXJlZEdyb3VwODgoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZFJlcXVpcmVkR3JvdXA4OChvdGhlci5nZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKTsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRUZXN0T25lb2ZDYXNlKCkpIHsKICAgICAgICAgIGNhc2UgRklFTERfRE9VQkxFXzUzOiB7CiAgICAgICAgICAgIHNldEZpZWxkRG91YmxlNTMob3RoZXIuZ2V0RmllbGREb3VibGU1MygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0ZMT0FUXzU0OiB7CiAgICAgICAgICAgIHNldEZpZWxkRmxvYXQ1NChvdGhlci5nZXRGaWVsZEZsb2F0NTQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9JTlQ2NF81NTogewogICAgICAgICAgICBzZXRGaWVsZEludDY0NTUob3RoZXIuZ2V0RmllbGRJbnQ2NDU1KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfVUlOVDY0XzU2OiB7CiAgICAgICAgICAgIHNldEZpZWxkVWludDY0NTYob3RoZXIuZ2V0RmllbGRVaW50NjQ1NigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0lOVDMyXzU3OiB7CiAgICAgICAgICAgIHNldEZpZWxkSW50MzI1NyhvdGhlci5nZXRGaWVsZEludDMyNTcoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9GSVhFRDY0XzU4OiB7CiAgICAgICAgICAgIHNldEZpZWxkRml4ZWQ2NDU4KG90aGVyLmdldEZpZWxkRml4ZWQ2NDU4KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfRklYRUQzMl81OTogewogICAgICAgICAgICBzZXRGaWVsZEZpeGVkMzI1OShvdGhlci5nZXRGaWVsZEZpeGVkMzI1OSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0JPT0xfNjA6IHsKICAgICAgICAgICAgc2V0RmllbGRCb29sNjAob3RoZXIuZ2V0RmllbGRCb29sNjAoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TVFJJTkdfNjE6IHsKICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG90aGVyLnRlc3RPbmVvZl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfTUVTU0FHRV82MjogewogICAgICAgICAgICBtZXJnZUZpZWxkTWVzc2FnZTYyKG90aGVyLmdldEZpZWxkTWVzc2FnZTYyKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfQllURVNfNjM6IHsKICAgICAgICAgICAgc2V0RmllbGRCeXRlczYzKG90aGVyLmdldEZpZWxkQnl0ZXM2MygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1VJTlQzMl82NDogewogICAgICAgICAgICBzZXRGaWVsZFVpbnQzMjY0KG90aGVyLmdldEZpZWxkVWludDMyNjQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TRklYRUQzMl82NTogewogICAgICAgICAgICBzZXRGaWVsZFNmaXhlZDMyNjUob3RoZXIuZ2V0RmllbGRTZml4ZWQzMjY1KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfU0ZJWEVENjRfNjY6IHsKICAgICAgICAgICAgc2V0RmllbGRTZml4ZWQ2NDY2KG90aGVyLmdldEZpZWxkU2ZpeGVkNjQ2NigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1NJTlQzMl82NzogewogICAgICAgICAgICBzZXRGaWVsZFNpbnQzMjY3KG90aGVyLmdldEZpZWxkU2ludDMyNjcoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TSU5UNjRfNjg6IHsKICAgICAgICAgICAgc2V0RmllbGRTaW50NjQ2OChvdGhlci5nZXRGaWVsZFNpbnQ2NDY4KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERHUk9VUDY5OiB7CiAgICAgICAgICAgIG1lcmdlRmllbGRHcm91cDY5KG90aGVyLmdldEZpZWxkR3JvdXA2OSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIFRFU1RPTkVPRl9OT1RfU0VUOiB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRG91YmxlNzEoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRGbG9hdDcyKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkSW50NjQ3MygpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFVpbnQ2NDc0KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEZpeGVkNjQ3NigpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEZpeGVkMzI3NygpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZEJvb2w3OCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFN0cmluZzc5KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkRW51bTgzKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNGaWVsZFJlcXVpcmVkR3JvdXA4OCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2UxMCgpKSB7CiAgICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTEwKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdDb3VudCgpOyBpKyspIHsKICAgICAgICAgIGlmICghZ2V0RmllbGRNZXNzYWdlTGlzdDI3KGkpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2U2MigpKSB7CiAgICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTYyKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDk6IHsKICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlMV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOQogICAgICAgICAgICAgIGNhc2UgMjE6IHsKICAgICAgICAgICAgICAgIGZpZWxkRmxvYXQyXyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxCiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgZmllbGRJbnQ2NDNfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBmaWVsZFVpbnQ2NDRfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgZmllbGRJbnQzMjVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDQ5OiB7CiAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjQ2XyA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDkKICAgICAgICAgICAgICBjYXNlIDYxOiB7CiAgICAgICAgICAgICAgICBmaWVsZEZpeGVkMzI3XyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjEKICAgICAgICAgICAgICBjYXNlIDY0OiB7CiAgICAgICAgICAgICAgICBmaWVsZEJvb2w4XyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBmaWVsZFN0cmluZzlfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2UxMEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBmaWVsZEJ5dGVzMTFfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk2OiB7CiAgICAgICAgICAgICAgICBmaWVsZFVpbnQzMjEyXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NgogICAgICAgICAgICAgIGNhc2UgMTA0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTMsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBmaWVsZEVudW0xM18gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDQKICAgICAgICAgICAgICBjYXNlIDExNzogewogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNwogICAgICAgICAgICAgIGNhc2UgMTIxOiB7CiAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0MTVfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxCiAgICAgICAgICAgICAgY2FzZSAxMjg6IHsKICAgICAgICAgICAgICAgIGZpZWxkU2ludDMyMTZfID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyOAogICAgICAgICAgICAgIGNhc2UgMTM2OiB7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzYKICAgICAgICAgICAgICBjYXNlIDE0NTogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLmFkZERvdWJsZSh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDUKICAgICAgICAgICAgICBjYXNlIDE0NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5hZGREb3VibGUoaW5wdXQucmVhZERvdWJsZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgICBjYXNlIDE1NzogewogICAgICAgICAgICAgICAgZmxvYXQgdiA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGbG9hdExpc3QxOV8uYWRkRmxvYXQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU3CiAgICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdDE5SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQKICAgICAgICAgICAgICBjYXNlIDE2MDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MAogICAgICAgICAgICAgIGNhc2UgMTYyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0MjBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYyCiAgICAgICAgICAgICAgY2FzZSAxNjg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgKICAgICAgICAgICAgICBjYXNlIDE3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3MAogICAgICAgICAgICAgIGNhc2UgMTc2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3QyMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3NgogICAgICAgICAgICAgIGNhc2UgMTc4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzgKICAgICAgICAgICAgICBjYXNlIDE4NTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4NQogICAgICAgICAgICAgIGNhc2UgMTg2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODYKICAgICAgICAgICAgICBjYXNlIDE5NzogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdDI0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTcKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEludChpbnB1dC5yZWFkRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMDogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1Xy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMAogICAgICAgICAgICAgIGNhc2UgMjAyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQm9vbGVhbihpbnB1dC5yZWFkQm9vbCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDIKICAgICAgICAgICAgICBjYXNlIDIxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHYgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLmFkZCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMjYKICAgICAgICAgICAgICBjYXNlIDIzMjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMzIKICAgICAgICAgICAgICBjYXNlIDIzNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjM0CiAgICAgICAgICAgICAgY2FzZSAyNDA6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgzMCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MAogICAgICAgICAgICAgIGNhc2UgMjQyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgzMCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQyCiAgICAgICAgICAgICAgY2FzZSAyNTM6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjUzCiAgICAgICAgICAgICAgY2FzZSAyNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjUwCiAgICAgICAgICAgICAgY2FzZSAyNTc6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTcKICAgICAgICAgICAgICBjYXNlIDI1ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU4CiAgICAgICAgICAgICAgY2FzZSAyNjQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY0CiAgICAgICAgICAgICAgY2FzZSAyNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NgogICAgICAgICAgICAgIGNhc2UgMjcyOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjcyCiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfLmFkZExvbmcoaW5wdXQucmVhZFNJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzQKICAgICAgICAgICAgICBjYXNlIDI4MTogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZERvdWJsZSh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODEKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5hZGREb3VibGUoaW5wdXQucmVhZERvdWJsZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODIKICAgICAgICAgICAgICBjYXNlIDI5MzogewogICAgICAgICAgICAgICAgZmxvYXQgdiA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uYWRkRmxvYXQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjkzCiAgICAgICAgICAgICAgY2FzZSAyOTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTAKICAgICAgICAgICAgICBjYXNlIDI5NjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5NgogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjk4CiAgICAgICAgICAgICAgY2FzZSAzMDQ6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDQKICAgICAgICAgICAgICBjYXNlIDMwNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNgogICAgICAgICAgICAgIGNhc2UgMzEyOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxMgogICAgICAgICAgICAgIGNhc2UgMzE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMTQKICAgICAgICAgICAgICBjYXNlIDMyMTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMQogICAgICAgICAgICAgIGNhc2UgMzIyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjIKICAgICAgICAgICAgICBjYXNlIDMzMzogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzMKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEludChpbnB1dC5yZWFkRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzAKICAgICAgICAgICAgICBjYXNlIDMzNjogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzNgogICAgICAgICAgICAgIGNhc2UgMzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uYWRkQm9vbGVhbihpbnB1dC5yZWFkQm9vbCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzgKICAgICAgICAgICAgICBjYXNlIDM0NDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNDQKICAgICAgICAgICAgICBjYXNlIDM0NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ2CiAgICAgICAgICAgICAgY2FzZSAzNTI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg0NCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM1MgogICAgICAgICAgICAgIGNhc2UgMzU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg0NCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzU0CiAgICAgICAgICAgICAgY2FzZSAzNjU6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzY1CiAgICAgICAgICAgICAgY2FzZSAzNjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzYyCiAgICAgICAgICAgICAgY2FzZSAzNjk6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjkKICAgICAgICAgICAgICBjYXNlIDM3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzcwCiAgICAgICAgICAgICAgY2FzZSAzNzY6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0UGFja2VkNDdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzc2CiAgICAgICAgICAgICAgY2FzZSAzNzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0UGFja2VkNDdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3OAogICAgICAgICAgICAgIGNhc2UgMzg0OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzg0CiAgICAgICAgICAgICAgY2FzZSAzODY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmFkZExvbmcoaW5wdXQucmVhZFNJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzODYKICAgICAgICAgICAgICBjYXNlIDM5NTogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDQ5LAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkR3JvdXA0OUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzk1CiAgICAgICAgICAgICAgY2FzZSA0MTE6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCg1MSwKICAgICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTEKICAgICAgICAgICAgICBjYXNlIDQyNTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDI1CiAgICAgICAgICAgICAgY2FzZSA0Mzc6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDM3CiAgICAgICAgICAgICAgY2FzZSA0NDA6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDQwCiAgICAgICAgICAgICAgY2FzZSA0NDg6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU2OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0OAogICAgICAgICAgICAgIGNhc2UgNDU2OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU3OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1NgogICAgICAgICAgICAgIGNhc2UgNDY1OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDY1CiAgICAgICAgICAgICAgY2FzZSA0Nzc6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1OTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NzcKICAgICAgICAgICAgICBjYXNlIDQ4MDogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4MAogICAgICAgICAgICAgIGNhc2UgNDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjE7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gYnM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDkwCiAgICAgICAgICAgICAgY2FzZSA0OTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTYyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDk4CiAgICAgICAgICAgICAgY2FzZSA1MDY6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTA2CiAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxMgogICAgICAgICAgICAgIGNhc2UgNTI1OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY1OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyNQogICAgICAgICAgICAgIGNhc2UgNTI5OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY2OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyOQogICAgICAgICAgICAgIGNhc2UgNTM2OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MzYKICAgICAgICAgICAgICBjYXNlIDU0NDogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTQ0CiAgICAgICAgICAgICAgY2FzZSA1NTU6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCg2OSwKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZEdyb3VwNjlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2OTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NTUKICAgICAgICAgICAgICBjYXNlIDU2OTogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZERvdWJsZTcxXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NjkKICAgICAgICAgICAgICBjYXNlIDU4MTogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZEZsb2F0NzJfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgxCiAgICAgICAgICAgICAgY2FzZSA1ODQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRJbnQ2NDczXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4NAogICAgICAgICAgICAgIGNhc2UgNTkyOiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkVWludDY0NzRfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU5MgogICAgICAgICAgICAgIGNhc2UgNjAwOiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkSW50MzI3NV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MDAKICAgICAgICAgICAgICBjYXNlIDYwOTogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYwOQogICAgICAgICAgICAgIGNhc2UgNjIxOiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3XyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjIxCiAgICAgICAgICAgICAgY2FzZSA2MjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRCb29sNzhfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MjQKICAgICAgICAgICAgICBjYXNlIDYzNDogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYzNAogICAgICAgICAgICAgIGNhc2UgNjQyOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NDIKICAgICAgICAgICAgICBjYXNlIDY1MDogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZEJ5dGVzODFfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUwCiAgICAgICAgICAgICAgY2FzZSA2NTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjU2CiAgICAgICAgICAgICAgY2FzZSA2NjQ6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg4MywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRFbnVtODNfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjY0CiAgICAgICAgICAgICAgY2FzZSA2Nzc6IHsKICAgICAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0XyA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY3NwogICAgICAgICAgICAgIGNhc2UgNjgxOiB7CiAgICAgICAgICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV8gPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODEKICAgICAgICAgICAgICBjYXNlIDY4ODogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODgKICAgICAgICAgICAgICBjYXNlIDY5NjogewogICAgICAgICAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQ2NDg3XyA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2OTYKICAgICAgICAgICAgICBjYXNlIDcwNzogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDg4LAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MDcKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCB0ZXN0T25lb2ZfOwogICAgICBwdWJsaWMgVGVzdE9uZW9mQ2FzZQogICAgICAgICAgZ2V0VGVzdE9uZW9mQ2FzZSgpIHsKICAgICAgICByZXR1cm4gVGVzdE9uZW9mQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUZXN0T25lb2YoKSB7CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDJfOwoKICAgICAgcHJpdmF0ZSBkb3VibGUgZmllbGREb3VibGUxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGUxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlMSgpIHsKICAgICAgICByZXR1cm4gZmllbGREb3VibGUxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGUxKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBmaWVsZERvdWJsZTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZERvdWJsZTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkRG91YmxlMV8gPSAwRDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmbG9hdCBmaWVsZEZsb2F0Ml8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGbG9hdDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDIoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdDIoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGbG9hdDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdDIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGZpZWxkRmxvYXQyXyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRJbnQ2NDNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDMoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjQzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NDMobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZEludDY0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZmllbGRJbnQ2NDNfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZFVpbnQ2NDRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0NCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjQ0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjQ0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRVaW50NjQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50NjQ0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjUoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjUoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkSW50MzI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBmaWVsZEludDMyNV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRGaXhlZDY0Nl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBmaWVsZF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkNjQ2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDY0NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NDYoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NDZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjQ2KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDY0NigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRGaXhlZDMyN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyNygpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQzMjcoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGZpZWxkQm9vbDhfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQm9vbDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w4LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2w4KCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2w4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2w4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sOChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGZpZWxkQm9vbDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQm9vbDgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGZpZWxkQm9vbDhfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZFN0cmluZzlfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFN0cmluZzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTdHJpbmc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBmaWVsZFN0cmluZzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTdHJpbmc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRTdHJpbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmc5KCkgewogICAgICAgIGZpZWxkU3RyaW5nOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZFN0cmluZzkoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRTdHJpbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRNZXNzYWdlMTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1lc3NhZ2UxMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2UxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNZXNzYWdlMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWVzc2FnZTEwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2UxMCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZE1lc3NhZ2UxMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRNZXNzYWdlMTBfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRNZXNzYWdlMTBfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2UxMEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlMTBCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNZXNzYWdlMTBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxME9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlMTBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQnl0ZXMxMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXMxMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzMTFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzMTEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZEJ5dGVzMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJ5dGVzMTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZEJ5dGVzMTEoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRVaW50MzIxMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQzMjEyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50MzIxMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyMTIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzIxMigpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzIxMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50MzIxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDMyMTIoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkVWludDMyMTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZmllbGRfdWludDMyXzEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDMyMTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGZpZWxkVWludDMyMTJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRFbnVtMTNfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRW51bTEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRmllbGRFbnVtMTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtMTMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtMTMoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRFbnVtMTNfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTyA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRFbnVtMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEVudW0xMyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBmaWVsZEVudW0xM18gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRFbnVtMTMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkMzIxNF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjE0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjE0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzIxNC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyMTQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzIxNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzIxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkMzIxNChpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQzMjE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ZpeGVkNjQxNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDE1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQ2NDE1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQxNS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDE1KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0MTUobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFNmaXhlZDY0MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGZpZWxkU2ZpeGVkNjQxNV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50MzIxNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQzMjE2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyMTYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50MzIxNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50MzIxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ludDMyMTYoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkU2ludDMyMTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZmllbGRfc2ludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDMyMTYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGZpZWxkU2ludDMyMTZfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ludDY0MTdfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBmaWVsZF9zaW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQxNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0MTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDE3LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NDE3KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NDE3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NDE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjQxNyhsb25nIHZhbHVlKSB7CgogICAgICAgIGZpZWxkU2ludDY0MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGZpZWxkU2ludDY0MTdfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZERvdWJsZUxpc3QxOF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGREb3VibGVMaXN0MThfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGREb3VibGVMaXN0MThfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKSB7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0MThfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRG91YmxlTGlzdDE4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGVMaXN0MTggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3QxOChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0MThfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGVMaXN0MTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZERvdWJsZUxpc3QxOCgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGVMaXN0MTggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZERvdWJsZUxpc3QxOChkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8uYWRkRG91YmxlKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZERvdWJsZUxpc3QxOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRG91YmxlTGlzdDE4KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGREb3VibGVMaXN0MTgoKSB7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEZsb2F0TGlzdDE5Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZsb2F0TGlzdDE5Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGbG9hdExpc3QxOV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKSB7CiAgICAgICAgZmllbGRGbG9hdExpc3QxOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdDE5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdDE5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZsb2F0TGlzdDE5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3QxOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZsb2F0TGlzdDE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdExpc3QxOSgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdExpc3QxOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRmxvYXRMaXN0MTkoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLmFkZEZsb2F0KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRGbG9hdExpc3QxOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRmxvYXRMaXN0MTkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEZsb2F0TGlzdDE5Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdExpc3QxOSgpIHsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRJbnQ2NExpc3QyMF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkSW50NjRMaXN0MjBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpIHsKICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50NjRMaXN0MjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdDIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjRMaXN0MjAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0TGlzdDIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NExpc3QyMCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjRMaXN0MjAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEludDY0TGlzdDIwKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEludDY0TGlzdDIwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRJbnQ2NExpc3QyMCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0MjBJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRJbnQ2NExpc3QyMF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50NjRMaXN0MjAoKSB7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRVaW50NjRMaXN0MjFfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFVpbnQ2NExpc3QyMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFVpbnQ2NExpc3QyMV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpIHsKICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3QyMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NExpc3QyMShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0TGlzdDIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjRMaXN0MjEoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjRMaXN0MjEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFVpbnQ2NExpc3QyMShsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkVWludDY0TGlzdDIxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRVaW50NjRMaXN0MjEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFVpbnQ2NExpc3QyMV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50NjRMaXN0MjEoKSB7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEludDMyTGlzdDIyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRJbnQzMkxpc3QyMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQzMkxpc3QyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkgewogICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0MjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdDIyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyTGlzdDIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMkxpc3QyMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyTGlzdDIyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRJbnQzMkxpc3QyMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3QyMklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkSW50MzJMaXN0MjIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEludDMyTGlzdDIyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3QyMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEludDMyTGlzdDIyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMkxpc3QyMigpIHsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkRml4ZWQ2NExpc3QyM18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkNjRMaXN0MjNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQ2NExpc3QyM18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQ2NExpc3QyM18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDY0TGlzdDIzXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKSB7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NExpc3QyMyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdDIzXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQ2NExpc3QyMygKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGaXhlZDY0TGlzdDIzKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRml4ZWQ2NExpc3QyMygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEZpeGVkNjRMaXN0MjNfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDY0TGlzdDIzKCkgewogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEZpeGVkMzJMaXN0MjRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkMzJMaXN0MjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQzMkxpc3QyNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQzMkxpc3QyNF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDMyTGlzdDI0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQzMkxpc3QyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKSB7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQzMkxpc3QyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkMzJMaXN0MjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZpeGVkMzJMaXN0MjQoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRml4ZWQzMkxpc3QyNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkRml4ZWQzMkxpc3QyNCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDMyTGlzdDI0KCkgewogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRCb29sTGlzdDI1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJvb2xMaXN0MjVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEJvb2xMaXN0MjVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkQm9vbExpc3QyNV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJvb2xMaXN0MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkgewogICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkQm9vbExpc3QyNUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3QyNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0MjUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3QyNV8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2xMaXN0MjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJvb2xMaXN0MjUoCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCb29sTGlzdDI1Xy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbExpc3QyNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkQm9vbExpc3QyNShib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEJvb2xMaXN0MjUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEJvb2xMaXN0MjUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQm9vbExpc3QyNSgpIHsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTdHJpbmdMaXN0MjZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KGZpZWxkU3RyaW5nTGlzdDI2Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRGaWVsZFN0cmluZ0xpc3QyNkxpc3QoKSB7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU3RyaW5nTGlzdDI2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmdMaXN0MjYoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTdHJpbmdMaXN0MjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFN0cmluZ0xpc3QyNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTdHJpbmdMaXN0MjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFN0cmluZ0xpc3QyNigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFN0cmluZ0xpc3QyNl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmdMaXN0MjYoKSB7CiAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFN0cmluZ0xpc3QyNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGZpZWxkTWVzc2FnZUxpc3QyN18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPihmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWVzc2FnZUxpc3QyNyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgZmllbGRNZXNzYWdlTGlzdDI3Xyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNZXNzYWdlTGlzdDI3KCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgYWRkRmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkQnl0ZXNMaXN0MjhfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJ5dGVzTGlzdDI4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkgewogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCeXRlc0xpc3QyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXNMaXN0MjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzTGlzdDI4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzTGlzdDI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCeXRlc0xpc3QyOCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZEJ5dGVzTGlzdDI4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCeXRlc0xpc3QyOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkQnl0ZXNMaXN0MjgoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZEJ5dGVzTGlzdDI4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRCeXRlc0xpc3QyOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkQnl0ZXNMaXN0MjgoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEJ5dGVzTGlzdDI4Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCeXRlc0xpc3QyOCgpIHsKICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRVaW50MzJMaXN0MjlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkVWludDMyTGlzdDI5Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkVWludDMyTGlzdDI5Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkgewogICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdDI5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdDI5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMkxpc3QyOUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyTGlzdDI5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjkoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdDI5Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDMyTGlzdDI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzJMaXN0MjkoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDMyTGlzdDI5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRVaW50MzJMaXN0MjkoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRVaW50MzJMaXN0MjkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFVpbnQzMkxpc3QyOSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkVWludDMyTGlzdDI5Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQzMkxpc3QyOSgpIHsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGZpZWxkRW51bUxpc3QzMF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KGZpZWxkRW51bUxpc3QzMF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEVudW1MaXN0MzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0MzBMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdDMwXywgZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3QzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0MzAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfLmNvbnZlcnQoZmllbGRFbnVtTGlzdDMwXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRFbnVtTGlzdDMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRFbnVtTGlzdDMwKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3QzMF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEVudW1MaXN0MzAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEVudW1MaXN0MzAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRFbnVtTGlzdDMwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdDMwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRFbnVtTGlzdDMwKCkgewogICAgICAgIGZpZWxkRW51bUxpc3QzMF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkMzJMaXN0MzFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDMyTGlzdDMxXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkMzJMaXN0MzFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDMyTGlzdDMxXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTZml4ZWQzMkxpc3QzMSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0MzFJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQzMkxpc3QzMShpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNmaXhlZDMyTGlzdDMxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNmaXhlZDMyTGlzdDMxXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQzMkxpc3QzMSgpIHsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkNjRMaXN0MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDY0TGlzdDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkNjRMaXN0MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDY0TGlzdDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0TGlzdDMyKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ZpeGVkNjRMaXN0MzIobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNmaXhlZDY0TGlzdDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNmaXhlZDY0TGlzdDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQ2NExpc3QzMigpIHsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFNpbnQzMkxpc3QzM18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNpbnQzMkxpc3QzM18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzNDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyTGlzdDMzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM18uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ludDMyTGlzdDMzKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDMyTGlzdDMzKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ludDMyTGlzdDMzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRTaW50MzJMaXN0MzMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNpbnQzMkxpc3QzM18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzJMaXN0MzMoKSB7CiAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTaW50NjRMaXN0MzRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFNpbnQ2NExpc3QzNF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNpbnQ2NExpc3QzNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3QzNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NExpc3QzNChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDY0TGlzdDM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjRMaXN0MzQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0MzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNpbnQ2NExpc3QzNChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ludDY0TGlzdDM0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRTaW50NjRMaXN0MzQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNpbnQ2NExpc3QzNF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50NjRMaXN0MzQoKSB7CiAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpIHsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uZ2V0RG91YmxlKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGREb3VibGVMaXN0UGFja2VkMzUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZERvdWJsZUxpc3RQYWNrZWQzNSgpIHsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpIHsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5nZXRGbG9hdChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGbG9hdExpc3RQYWNrZWQzNihmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRGbG9hdExpc3RQYWNrZWQzNigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KCkgewogICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkgewogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzNyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkSW50NjRMaXN0UGFja2VkMzcobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEludDY0TGlzdFBhY2tlZDM3KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQ2NExpc3RQYWNrZWQzNygpIHsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkgewogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCgpIHsKICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEludDMyTGlzdFBhY2tlZDM5Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKSB7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzkoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEludDMyTGlzdFBhY2tlZDM5KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkSW50MzJMaXN0UGFja2VkMzkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyTGlzdFBhY2tlZDM5KCkgewogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpIHsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoKSB7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpIHsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoKSB7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCb29sTGlzdFBhY2tlZDQyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKSB7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5nZXRCb29sZWFuKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQm9vbExpc3RQYWNrZWQ0MigKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRCb29sTGlzdFBhY2tlZDQyKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkQm9vbExpc3RQYWNrZWQ0MigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEJvb2xMaXN0UGFja2VkNDJfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCb29sTGlzdFBhY2tlZDQyKCkgewogICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSB7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MygKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDMyTGlzdFBhY2tlZDQzKCkgewogICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4oZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPihmaWVsZEVudW1MaXN0UGFja2VkNDRfLCBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8uY29udmVydChmaWVsZEVudW1MaXN0UGFja2VkNDRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEVudW1MaXN0UGFja2VkNDQoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3RQYWNrZWQ0NChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEVudW1MaXN0UGFja2VkNDQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEVudW1MaXN0UGFja2VkNDQoKSB7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nihsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkgZmllbGRHcm91cDQ5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5T3JCdWlsZGVyPiBmaWVsZEdyb3VwNDlCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRncm91cDQ5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkR3JvdXA0OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkZ3JvdXA0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IGdldEZpZWxkR3JvdXA0OSgpIHsKICAgICAgICBpZiAoZmllbGRHcm91cDQ5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXA0OV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEdyb3VwNDlfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRHcm91cDQ5QnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkR3JvdXA0OShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRHcm91cDQ5XyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGaWVsZEdyb3VwNDkgPSA0OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRHcm91cDQ5KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNDlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEdyb3VwNDlfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXA0OUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkR3JvdXA0OShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5IHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZEdyb3VwNDlfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRHcm91cDQ5XyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkR3JvdXA0OUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRHcm91cDQ5XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwNDlCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRHcm91cDQ5XyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkR3JvdXA0OSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgZmllbGRHcm91cDQ5XyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkR3JvdXA0OUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkR3JvdXA0OUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OS5CdWlsZGVyIGdldEZpZWxkR3JvdXA0OUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGaWVsZEdyb3VwNDlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZpZWxkR3JvdXA0OSA9IDQ5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OU9yQnVpbGRlciBnZXRGaWVsZEdyb3VwNDlPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNDlfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEdyb3VwNDlfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRmllbGRHcm91cDQ5ID0gNDkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDksIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNDkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZEdyb3VwNDlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA0OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkR3JvdXA0OUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA0OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDQ5T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGRHcm91cDQ5KCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZEdyb3VwNDlfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXA0OUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxPiBmaWVsZEdyb3VwTGlzdDUxXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxPihmaWVsZEdyb3VwTGlzdDUxXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXI+IGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MT4gZ2V0RmllbGRHcm91cExpc3Q1MUxpc3QoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRHcm91cExpc3Q1MUNvdW50KCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RmllbGRHcm91cExpc3Q1MShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEdyb3VwTGlzdDUxKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEdyb3VwTGlzdDUxKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRHcm91cExpc3Q1MShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRHcm91cExpc3Q1MSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlRmllbGRHcm91cExpc3Q1MUlzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRHcm91cExpc3Q1MSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRHcm91cExpc3Q1MSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkR3JvdXBMaXN0NTEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxPiB2YWx1ZXMpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkR3JvdXBMaXN0NTFJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIGZpZWxkR3JvdXBMaXN0NTFfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEdyb3VwTGlzdDUxKCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkR3JvdXBMaXN0NTEoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZEdyb3VwTGlzdDUxSXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciBnZXRGaWVsZEdyb3VwTGlzdDUxQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZEdyb3VwTGlzdDUxRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEZpZWxkR3JvdXBMaXN0NTEgPSA1MSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxT3JCdWlsZGVyIGdldEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBGaWVsZEdyb3VwTGlzdDUxID0gNTEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXI+IAogICAgICAgICAgIGdldEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXBMaXN0NTFCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRHcm91cExpc3Q1MV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciBhZGRGaWVsZEdyb3VwTGlzdDUxQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRHcm91cExpc3Q1MUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciBhZGRGaWVsZEdyb3VwTGlzdDUxQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZEdyb3VwTGlzdDUxRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgRmllbGRHcm91cExpc3Q1MSA9IDUxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0RmllbGRHcm91cExpc3Q1MUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZEdyb3VwTGlzdDUxRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZEdyb3VwTGlzdDUxRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRHcm91cExpc3Q1MUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cExpc3Q1MSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTEuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHgwMDAyMDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZEdyb3VwTGlzdDUxXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZEdyb3VwTGlzdDUxQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlNTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGREb3VibGU1MygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlNTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlNTMoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDUzKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Eb3VibGUpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwRDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV81MyA9IDUzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZERvdWJsZTUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGU1Myhkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1MzsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGREb3VibGU1MygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTMpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdDU0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRmxvYXQ1NCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0NTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDU0KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuRmxvYXQpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwRjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdDU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdDU0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTQ7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZsb2F0NTQoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50NjQ1NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDY0NTUoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU1OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NDU1LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDU1KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0NTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDY0NTUobG9uZyB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU1OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQ2NDU1KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NSkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50NjQ1NigpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTY7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NDU2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NikgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0NTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQ2NDU2KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NjsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50NjQ1NigpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjU3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1NygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTc7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1NygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTcpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyNTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyNTcoaW50IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTc7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyNTcoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkNjQ1OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0NTguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NDU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDY0NTgobG9uZyB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU4OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQ2NDU4KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OCkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDMyNTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNTkoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU5OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjU5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTkpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyNTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkMzI1OShpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1OTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTkpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQm9vbDYwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQm9vbDYwKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbDYwKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MCkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuQm9vbGVhbikgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sNjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJvb2w2MChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjA7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCb29sNjAoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYwKSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTdHJpbmc2MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU3RyaW5nNjEoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZzYxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzYxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc2MS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmc2MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmc2MSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc2MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYxOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlNjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2U2Mi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlNjIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2U2MigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRNZXNzYWdlNjIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyICYmCiAgICAgICAgICAgICAgdGVzdE9uZW9mXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl8pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWVzc2FnZTYyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2U2MkJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZTYyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2U2Mk9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKHRlc3RPbmVvZkNhc2VfID09IDYyKSAmJiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlNjJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCEodGVzdE9uZW9mQ2FzZV8gPT0gNjIpKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgdGVzdE9uZW9mXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXM2MygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXM2MygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzNjMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYzOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCeXRlczYzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyNjQoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NDsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzI2NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyNjUoaW50IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjU7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyNjUoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkNjQ2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDY2LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDY2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0NjYobG9uZyB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY2OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQ2NDY2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzI2NygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjc7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyNjcoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY3KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMjY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzI2NyhpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NzsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzI2NygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0NjgoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQ2OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NDY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjQ2OChsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjg7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDY0NjgoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5T3JCdWlsZGVyPiBmaWVsZEdyb3VwNjlCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRncm91cDY5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRHcm91cDY5KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2OTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRncm91cDY5LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSBnZXRGaWVsZEdyb3VwNjkoKSB7CiAgICAgICAgaWYgKGZpZWxkR3JvdXA2OUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkpIHRlc3RPbmVvZl87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNjlCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEdyb3VwNjkoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNjlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEdyb3VwNjlCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2OTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRmllbGRHcm91cDY5ID0gNjkgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkR3JvdXA2OSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRHcm91cDY5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgdGVzdE9uZW9mXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkR3JvdXA2OUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY5OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZEdyb3VwNjkoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNjlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjkgJiYKICAgICAgICAgICAgICB0ZXN0T25lb2ZfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OSkgdGVzdE9uZW9mXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICAgICBmaWVsZEdyb3VwNjlCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRHcm91cDY5QnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkR3JvdXA2OSgpIHsKICAgICAgICBpZiAoZmllbGRHcm91cDY5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY5KSB7CiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjkpIHsKICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkR3JvdXA2OUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGaWVsZEdyb3VwNjkgPSA2OSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuQnVpbGRlciBnZXRGaWVsZEdyb3VwNjlCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZEdyb3VwNjlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5T3JCdWlsZGVyIGdldEZpZWxkR3JvdXA2OU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKHRlc3RPbmVvZkNhc2VfID09IDY5KSAmJiAoZmllbGRHcm91cDY5QnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEdyb3VwNjlCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkpIHRlc3RPbmVvZl87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZpZWxkR3JvdXA2OSA9IDY5IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjlPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRHcm91cDY5RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEdyb3VwNjlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoISh0ZXN0T25lb2ZDYXNlXyA9PSA2OSkpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZEdyb3VwNjlCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjksIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZEdyb3VwNjkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkR3JvdXA2OU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHcm91cDY5KSB0ZXN0T25lb2ZfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkR3JvdXA2OUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGRvdWJsZSBmaWVsZFJlcXVpcmVkRG91YmxlNzFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZERvdWJsZTcxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZERvdWJsZTcxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIGZpZWxkX3JlcXVpcmVkX2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZERvdWJsZTcxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkUmVxdWlyZWREb3VibGU3MSgpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZERvdWJsZTcxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIGZpZWxkX3JlcXVpcmVkX2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkRG91YmxlNzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkRG91YmxlNzEoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGZpZWxkUmVxdWlyZWREb3VibGU3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSBmaWVsZF9yZXF1aXJlZF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZERvdWJsZTcxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBmaWVsZFJlcXVpcmVkRG91YmxlNzFfID0gMEQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgZmllbGRSZXF1aXJlZEZsb2F0NzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZsb2F0IGZpZWxkX3JlcXVpcmVkX2Zsb2F0XzcyID0gNzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRGbG9hdDcyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEZsb2F0NzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmbG9hdCBmaWVsZF9yZXF1aXJlZF9mbG9hdF83MiA9IDcyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEZsb2F0NzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZFJlcXVpcmVkRmxvYXQ3MigpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEZsb2F0NzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmbG9hdCBmaWVsZF9yZXF1aXJlZF9mbG9hdF83MiA9IDcyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkRmxvYXQ3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRGbG9hdDcyKGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGZpZWxkUmVxdWlyZWRGbG9hdDcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZmxvYXQgZmllbGRfcmVxdWlyZWRfZmxvYXRfNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZEZsb2F0NzIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGZpZWxkUmVxdWlyZWRGbG9hdDcyXyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZEludDY0NzNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDY0IGZpZWxkX3JlcXVpcmVkX2ludDY0XzczID0gNzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRJbnQ2NDczIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEludDY0NzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQ2NCBmaWVsZF9yZXF1aXJlZF9pbnQ2NF83MyA9IDczOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEludDY0NzMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkUmVxdWlyZWRJbnQ2NDczKCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkSW50NjQ3M187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDY0IGZpZWxkX3JlcXVpcmVkX2ludDY0XzczID0gNzM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRJbnQ2NDczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZEludDY0NzMobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkSW50NjQ3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDY0IGZpZWxkX3JlcXVpcmVkX2ludDY0XzczID0gNzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRJbnQ2NDczKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkSW50NjQ3M18gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkUmVxdWlyZWRVaW50NjQ3NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkVWludDY0NzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkVWludDY0NzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50NjQgZmllbGRfcmVxdWlyZWRfdWludDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkVWludDY0NzQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFVpbnQ2NDc0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDY0IGZpZWxkX3JlcXVpcmVkX3VpbnQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkVWludDY0NzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkVWludDY0NzQobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkVWludDY0NzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCB1aW50NjQgZmllbGRfcmVxdWlyZWRfdWludDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRVaW50NjQ3NCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgZmllbGRSZXF1aXJlZFVpbnQ2NDc0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkSW50MzI3NV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgZmllbGRfcmVxdWlyZWRfaW50MzJfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEludDMyNzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkSW50MzI3NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGZpZWxkX3JlcXVpcmVkX2ludDMyXzc1ID0gNzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkSW50MzI3NS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFJlcXVpcmVkSW50MzI3NSgpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEludDMyNzVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBmaWVsZF9yZXF1aXJlZF9pbnQzMl83NSA9IDc1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkSW50MzI3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRJbnQzMjc1KGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkSW50MzI3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGZpZWxkX3JlcXVpcmVkX2ludDMyXzc1ID0gNzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRJbnQzMjc1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkSW50MzI3NV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2ID0gNzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2ID0gNzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9maXhlZDY0Xzc2ID0gNzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRGaXhlZDY0NzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkNjQ3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkNjQgZmllbGRfcmVxdWlyZWRfZml4ZWQ2NF83NiA9IDc2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkRml4ZWQ2NDc2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkRml4ZWQ2NDc2XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEZpeGVkMzI3NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRGaXhlZDMyNzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX2ZpeGVkMzJfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRGaXhlZDMyNzcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRSZXF1aXJlZEZpeGVkMzI3NygpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEZpeGVkMzI3N187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgZmllbGRfcmVxdWlyZWRfZml4ZWQzMl83NyA9IDc3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZEZpeGVkMzI3NyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZEZpeGVkMzI3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgZmllbGRfcmVxdWlyZWRfZml4ZWQzMl83NyA9IDc3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkRml4ZWQzMjc3KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkRml4ZWQzMjc3XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBmaWVsZFJlcXVpcmVkQm9vbDc4XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBib29sIGZpZWxkX3JlcXVpcmVkX2Jvb2xfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEJvb2w3OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRCb29sNzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBib29sIGZpZWxkX3JlcXVpcmVkX2Jvb2xfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRCb29sNzguCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkUmVxdWlyZWRCb29sNzgoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRCb29sNzhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBib29sIGZpZWxkX3JlcXVpcmVkX2Jvb2xfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEJvb2w3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRCb29sNzgoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkQm9vbDc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYm9vbCBmaWVsZF9yZXF1aXJlZF9ib29sXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRCb29sNzgoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRCb29sNzhfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTdHJpbmc3OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU3RyaW5nNzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRSZXF1aXJlZFN0cmluZzc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZFN0cmluZzc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIGZpZWxkX3JlcXVpcmVkX3N0cmluZ183OSA9IDc5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkU3RyaW5nNzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRTdHJpbmc3OSgpIHsKICAgICAgICBmaWVsZFJlcXVpcmVkU3RyaW5nNzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RmllbGRSZXF1aXJlZFN0cmluZzc5KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgZmllbGRfcmVxdWlyZWRfc3RyaW5nXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFJlcXVpcmVkU3RyaW5nNzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkU3RyaW5nNzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRSZXF1aXJlZFN0cmluZzc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRNZXNzYWdlODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKCkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRSZXF1aXJlZE1lc3NhZ2U4MChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDJfICYgMHgwMDAwMTAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gIT0gbnVsbCAmJgogICAgICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlIGZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRNZXNzYWdlODAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSBmaWVsZF9yZXF1aXJlZF9tZXNzYWdlXzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkUmVxdWlyZWRNZXNzYWdlODBPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRNZXNzYWdlODBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRNZXNzYWdlODBfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkTWVzc2FnZTgwXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UgZmllbGRfcmVxdWlyZWRfbWVzc2FnZV84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5SZXF1aXJlZE5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZFJlcXVpcmVkTWVzc2FnZTgwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkTWVzc2FnZTgwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlJlcXVpcmVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZE1lc3NhZ2U4MCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRSZXF1aXJlZE1lc3NhZ2U4MF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZE1lc3NhZ2U4MEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBmaWVsZFJlcXVpcmVkQnl0ZXM4MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyBmaWVsZF9yZXF1aXJlZF9ieXRlc184MSA9IDgxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFJlcXVpcmVkQnl0ZXM4MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRCeXRlczgxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgZmllbGRfcmVxdWlyZWRfYnl0ZXNfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRCeXRlczgxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkUmVxdWlyZWRCeXRlczgxKCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkQnl0ZXM4MV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRCeXRlczgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZEJ5dGVzODEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZFJlcXVpcmVkQnl0ZXM4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIGZpZWxkX3JlcXVpcmVkX2J5dGVzXzgxID0gODE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRCeXRlczgxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkQnl0ZXM4MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZFJlcXVpcmVkQnl0ZXM4MSgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkVWludDMyODJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQzMiBmaWVsZF9yZXF1aXJlZF91aW50MzJfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFVpbnQzMjgyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFVpbnQzMjgyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkUmVxdWlyZWRVaW50MzI4MigpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFVpbnQzMjgyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgdWludDMyIGZpZWxkX3JlcXVpcmVkX3VpbnQzMl84MiA9IDgyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkVWludDMyODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFJlcXVpcmVkVWludDMyODIoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkUmVxdWlyZWRVaW50MzI4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHVpbnQzMiBmaWVsZF9yZXF1aXJlZF91aW50MzJfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZFVpbnQzMjgyKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkVWludDMyODJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZEVudW04M18gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZEVudW04MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRFbnVtODMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfcmVxdWlyZWRfZW51bV84MyA9IDgzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZEVudW04My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZFJlcXVpcmVkRW51bTgzKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkUmVxdWlyZWRFbnVtODNfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTyA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZEVudW04MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRFbnVtODMoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgZmllbGRSZXF1aXJlZEVudW04M18gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX3JlcXVpcmVkX2VudW1fODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRSZXF1aXJlZEVudW04MygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZEVudW04M18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ZpeGVkMzIgZmllbGRfcmVxdWlyZWRfc2ZpeGVkMzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNmaXhlZDMyODQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX3NmaXhlZDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCgpIHsKICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZFNmaXhlZDMyODRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQzMiBmaWVsZF9yZXF1aXJlZF9zZml4ZWQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDMyIGZpZWxkX3JlcXVpcmVkX3NmaXhlZDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRTZml4ZWQzMjg0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkMzI4NF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX3NmaXhlZDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzZml4ZWQ2NCBmaWVsZF9yZXF1aXJlZF9zZml4ZWQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFNmaXhlZDY0ODUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkgewogICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX3NmaXhlZDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZFNmaXhlZDY0ODUobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNmaXhlZDY0IGZpZWxkX3JlcXVpcmVkX3NmaXhlZDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRTZml4ZWQ2NDg1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBmaWVsZFJlcXVpcmVkU2ZpeGVkNjQ4NV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50MzIgZmllbGRfcmVxdWlyZWRfc2ludDMyXzg2ID0gODY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkUmVxdWlyZWRTaW50MzI4NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkUmVxdWlyZWRTaW50MzI4NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQzMiBmaWVsZF9yZXF1aXJlZF9zaW50MzJfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkUmVxdWlyZWRTaW50MzI4Ni4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFJlcXVpcmVkU2ludDMyODYoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTaW50MzI4Nl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQzMiBmaWVsZF9yZXF1aXJlZF9zaW50MzJfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZFNpbnQzMjg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZFNpbnQzMjg2KGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZFJlcXVpcmVkU2ludDMyODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzaW50MzIgZmllbGRfcmVxdWlyZWRfc2ludDMyXzg2ID0gODY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkUmVxdWlyZWRTaW50MzI4NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQzMjg2XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZFJlcXVpcmVkU2ludDY0ODdfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRSZXF1aXJlZFNpbnQ2NDg3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZFNpbnQ2NDg3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDY0IGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84NyA9IDg3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRSZXF1aXJlZFNpbnQ2NDg3LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRTaW50NjQ4N187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHNpbnQ2NCBmaWVsZF9yZXF1aXJlZF9zaW50NjRfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRSZXF1aXJlZFNpbnQ2NDg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZFNpbnQ2NDg3KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRSZXF1aXJlZFNpbnQ2NDg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc2ludDY0IGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84NyA9IDg3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkU2ludDY0ODcoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwODAwMDApOwogICAgICAgIGZpZWxkUmVxdWlyZWRTaW50NjQ4N18gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODggZmllbGRSZXF1aXJlZEdyb3VwODhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXI+IGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRyZXF1aXJlZGdyb3VwODggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRSZXF1aXJlZEdyb3VwODgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkcmVxdWlyZWRncm91cDg4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCBnZXRGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEdyb3VwODhfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODguZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGdyb3VwIEZpZWxkUmVxdWlyZWRHcm91cDg4ID0gODggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkUmVxdWlyZWRHcm91cDg4KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZ3JvdXAgRmllbGRSZXF1aXJlZEdyb3VwODggPSA4OCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRSZXF1aXJlZEdyb3VwODgoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODguQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkUmVxdWlyZWRHcm91cDg4KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMl8gJiAweDAwMTAwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gIT0gbnVsbCAmJgogICAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZ3JvdXAgRmllbGRSZXF1aXJlZEdyb3VwODggPSA4OCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFJlcXVpcmVkR3JvdXA4OCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZ3JvdXAgRmllbGRSZXF1aXJlZEdyb3VwODggPSA4OCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4T3JCdWlsZGVyIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4T3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZFJlcXVpcmVkR3JvdXA4OEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkUmVxdWlyZWRHcm91cDg4XyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODguZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFJlcXVpcmVkR3JvdXA4OF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBncm91cCBGaWVsZFJlcXVpcmVkR3JvdXA4OCA9IDg4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRSZXF1aXJlZEdyb3VwODhPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRSZXF1aXJlZEdyb3VwODhGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkUmVxdWlyZWRHcm91cDg4QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkZpZWxkUmVxdWlyZWRHcm91cDg4LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5GaWVsZFJlcXVpcmVkR3JvdXA4OE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkUmVxdWlyZWRHcm91cDg4KCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZFJlcXVpcmVkR3JvdXA4OF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRSZXF1aXJlZEdyb3VwODhCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzJNZXNzYWdlTGl0ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFByb3RvMk1lc3NhZ2VMaXRlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZUxpdGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZUxpdGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFByb3RvMkVtcHR5TGl0ZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJFbXB0eUxpdGUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMkVtcHR5TGl0ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvMkVtcHR5TGl0ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJFbXB0eUxpdGUpCiAgICAgIFByb3RvMkVtcHR5TGl0ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUHJvdG8yRW1wdHlMaXRlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFByb3RvMkVtcHR5TGl0ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvMkVtcHR5TGl0ZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBQcm90bzJFbXB0eUxpdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMkVtcHR5TGl0ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yRW1wdHlMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJFbXB0eUxpdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJFbXB0eUxpdGUpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMkVtcHR5TGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMkVtcHR5TGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yRW1wdHlMaXRlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJFbXB0eUxpdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMkVtcHR5TGl0ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJFbXB0eUxpdGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMkVtcHR5TGl0ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMkVtcHR5TGl0ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzJFbXB0eUxpdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBQcm90bzJFbXB0eUxpdGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJFbXB0eUxpdGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yRW1wdHlMaXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yRW1wdHlMaXRlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPFByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnM+IHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucykKICAgICAgUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnM+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucykKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnModGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEZpZWxkR3JvdXA0OU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5GaWVsZEdyb3VwNDkpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEludDMyNTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTAuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDMyNTAoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuRmllbGRHcm91cDQ5fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRHcm91cDQ5IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLkZpZWxkR3JvdXA0OSkKICAgICAgRmllbGRHcm91cDQ5T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGaWVsZEdyb3VwNDkubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRmllbGRHcm91cDQ5KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRmllbGRHcm91cDQ5KCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZpZWxkR3JvdXA0OSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfRmllbGRHcm91cDQ5X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwNDlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5LmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81MF9GSUVMRF9OVU1CRVIgPSA1MDsKICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1MF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1MCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzI1MF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1MCwgZmllbGRJbnQzMjUwXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNTAsIGZpZWxkSW50MzI1MF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSkgb2JqOwoKICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1MCgpICE9IG90aGVyLmhhc0ZpZWxkSW50MzI1MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEludDMyNTAoKSkgewogICAgICAgIGlmIChnZXRGaWVsZEludDMyNTAoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEludDMyNTAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZpZWxkSW50MzI1MCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfNTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50MzI1MCgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuRmllbGRHcm91cDQ5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuRmllbGRHcm91cDQ5KQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDlPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwNDlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZpZWxkSW50MzI1MF8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX0ZpZWxkR3JvdXA0OV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyNTBfID0gZmllbGRJbnQzMjUwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRJbnQzMjUwKCkpIHsKICAgICAgICAgIHNldEZpZWxkSW50MzI1MChvdGhlci5nZXRGaWVsZEludDMyNTAoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgNDAwOiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDMyNTBfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1MF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjUwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1MC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTAoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzI1MF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzI1MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzI1MChpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRJbnQzMjUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMjUwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBmaWVsZEludDMyNTBfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5GaWVsZEdyb3VwNDkpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLkZpZWxkR3JvdXA0OSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDkgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZpZWxkR3JvdXA0OT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGaWVsZEdyb3VwNDk+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBGaWVsZEdyb3VwNDkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwNDk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cDQ5PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5GaWVsZEdyb3VwTGlzdDUxKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX2ludDMyXzUyID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjUyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLkZpZWxkR3JvdXBMaXN0NTF9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZEdyb3VwTGlzdDUxIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLkZpZWxkR3JvdXBMaXN0NTEpCiAgICAgIEZpZWxkR3JvdXBMaXN0NTFPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEZpZWxkR3JvdXBMaXN0NTEubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRmllbGRHcm91cExpc3Q1MShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZpZWxkR3JvdXBMaXN0NTEoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRmllbGRHcm91cExpc3Q1MSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfRmllbGRHcm91cExpc3Q1MV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNTJfRklFTERfTlVNQkVSID0gNTI7CiAgICBwcml2YXRlIGludCBmaWVsZEludDMyNTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTIoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyNTJfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNTIsIGZpZWxkSW50MzI1Ml8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUyLCBmaWVsZEludDMyNTJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEpIG9iajsKCiAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyNTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRJbnQzMjUyKCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGRJbnQzMjUyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQzMjUyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGaWVsZEludDMyNTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzUyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNTIoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5GaWVsZEdyb3VwTGlzdDUxfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuRmllbGRHcm91cExpc3Q1MSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBmaWVsZEludDMyNTJfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQzMjUyXyA9IGZpZWxkSW50MzI1Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEludDMyNTIoKSkgewogICAgICAgICAgc2V0RmllbGRJbnQzMjUyKG90aGVyLmdldEZpZWxkSW50MzI1MigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzI1Ml8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMjUyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjUyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1MigpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMjUyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfaW50MzJfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjUyKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZEludDMyNTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9pbnQzMl81MiA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyNTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkSW50MzI1Ml8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLkZpZWxkR3JvdXBMaXN0NTEpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLkZpZWxkR3JvdXBMaXN0NTEpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXBMaXN0NTEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwTGlzdDUxPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZpZWxkR3JvdXBMaXN0NTE+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBGaWVsZEdyb3VwTGlzdDUxIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RmllbGRHcm91cExpc3Q1MT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGaWVsZEdyb3VwTGlzdDUxPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEJvb2wxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBCb29sQm9vbDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xCeXRlczJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbERvdWJsZTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbERvdWJsZTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBCb29sRG91YmxlMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwQm9vbERvdWJsZTNPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEVudW00KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sSW50MzI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sSW50NjQ5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbEludDY0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU3RyaW5nMTUoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sVWludDY0MTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDY0MzQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjREb3VibGUzNygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJCeXRlczUzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRmxvYXQ1OCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMySW50MzI1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyVWludDY0NjhPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRCb29sNjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RG91YmxlNzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0SW50NjQ3N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0U2ludDMyODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0VWludDY0ODUoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJvb2wxMjAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJEb3VibGUxMjIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJVaW50MzIxMzUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCb29sMTM3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQnl0ZXMxNzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTaW50NjQxODQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMpCiAgICAgIFByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpOwogICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgIGNhc2UgMTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpOwogICAgICAgIGNhc2UgMTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgIGNhc2UgMTg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICBjYXNlIDE5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpOwogICAgICAgIGNhc2UgMjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgIGNhc2UgMjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICBjYXNlIDIyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCk7CiAgICAgICAgY2FzZSAyMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgY2FzZSAyNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKTsKICAgICAgICBjYXNlIDI2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgIGNhc2UgMjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICBjYXNlIDI4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgICAgIGNhc2UgMjk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgY2FzZSAzMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgY2FzZSAzMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAgICAgY2FzZSAzMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgY2FzZSAzMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgY2FzZSAzNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCk7CiAgICAgICAgY2FzZSAzNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgIGNhc2UgMzY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgY2FzZSAzNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCk7CiAgICAgICAgY2FzZSAzODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgIGNhc2UgMzk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICBjYXNlIDQwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCk7CiAgICAgICAgY2FzZSA0MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICBjYXNlIDQyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgIGNhc2UgNDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAgICAgY2FzZSA0NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgIGNhc2UgNDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgY2FzZSA0NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKTsKICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICBjYXNlIDQ4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICBjYXNlIDQ5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKTsKICAgICAgICBjYXNlIDUwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICBjYXNlIDUxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICBjYXNlIDUyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpOwogICAgICAgIGNhc2UgNTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICBjYXNlIDU1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpOwogICAgICAgIGNhc2UgNTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgY2FzZSA1NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKTsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICBjYXNlIDYwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpOwogICAgICAgIGNhc2UgNjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgIGNhc2UgNjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgIGNhc2UgNjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKTsKICAgICAgICBjYXNlIDY1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgY2FzZSA2NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKTsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgY2FzZSA2OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICBjYXNlIDcwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKTsKICAgICAgICBjYXNlIDcxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgY2FzZSA3MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICBjYXNlIDczOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgY2FzZSA3NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgY2FzZSA3NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCk7CiAgICAgICAgY2FzZSA3NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgY2FzZSA3ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICBjYXNlIDc5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKTsKICAgICAgICBjYXNlIDgwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICBjYXNlIDgxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgY2FzZSA4MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpOwogICAgICAgIGNhc2UgODM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICBjYXNlIDg0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgY2FzZSA4NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpOwogICAgICAgIGNhc2UgODY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgY2FzZSA4NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgY2FzZSA4ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpOwogICAgICAgIGNhc2UgODk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgY2FzZSA5MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICBjYXNlIDkxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpOwogICAgICAgIGNhc2UgOTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgIGNhc2UgOTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgIGNhc2UgOTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgICAgIGNhc2UgOTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgY2FzZSA5NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgY2FzZSA5NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCk7CiAgICAgICAgY2FzZSA5ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgIGNhc2UgOTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICBjYXNlIDEwMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKTsKICAgICAgICBjYXNlIDEwMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICBjYXNlIDEwMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCk7CiAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICBjYXNlIDEwNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICBjYXNlIDEwNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCk7CiAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgIGNhc2UgMTA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICBjYXNlIDEwOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpOwogICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICBjYXNlIDExMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCk7CiAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICBjYXNlIDExNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgIGNhc2UgMTE1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpOwogICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgIGNhc2UgMTE3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgIGNhc2UgMTE4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgIGNhc2UgMTIwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgY2FzZSAxMjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCk7CiAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgIGNhc2UgMTIzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgY2FzZSAxMjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKTsKICAgICAgICBjYXNlIDEyNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgIGNhc2UgMTI2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgIGNhc2UgMTI3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpOwogICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgIGNhc2UgMTI5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgY2FzZSAxMzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgY2FzZSAxMzI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgIGNhc2UgMTMzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgY2FzZSAxMzU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgIGNhc2UgMTM2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgIGNhc2UgMTM4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgIGNhc2UgMTM5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgIGNhc2UgMTQxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgY2FzZSAxNDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKTsKICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICBjYXNlIDE0NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICBjYXNlIDE0NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKTsKICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgIGNhc2UgMTQ3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgIGNhc2UgMTQ4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpOwogICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICBjYXNlIDE1MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgY2FzZSAxNTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpOwogICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICBjYXNlIDE1MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgY2FzZSAxNTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKTsKICAgICAgICBjYXNlIDE1NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICBjYXNlIDE1NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgY2FzZSAxNTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKTsKICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgIGNhc2UgMTU5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgY2FzZSAxNjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgY2FzZSAxNjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgY2FzZSAxNjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICBjYXNlIDE2NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICBjYXNlIDE2NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCk7CiAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgIGNhc2UgMTY4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICBjYXNlIDE2OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCk7CiAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgIGNhc2UgMTcxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgY2FzZSAxNzI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCk7CiAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgIGNhc2UgMTc0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgY2FzZSAxNzU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgIGNhc2UgMTc3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgIGNhc2UgMTc4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpOwogICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgIGNhc2UgMTgwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgY2FzZSAxODE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCk7CiAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgY2FzZSAxODM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgIGNhc2UgMTg0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKTsKICAgICAgICBjYXNlIDE4NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgY2FzZSAxODY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgIGNhc2UgMTg3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKTsKICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgIGNhc2UgMTg5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgIGNhc2UgMTkwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKTsKICAgICAgICBjYXNlIDE5MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgIGNhc2UgMTkyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgY2FzZSAxOTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKTsKICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICBjYXNlIDE5NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICBjYXNlIDE5NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKTsKICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgIGNhc2UgMTk4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgIGNhc2UgMTk5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpOwogICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICBjYXNlIDIwMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICBjYXNlIDIwNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfQk9PTF8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xCb29sMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEJvb2wxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQm9vbDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xCb29sMSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9CWVRFU18yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwQm9vbEJ5dGVzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sQnl0ZXMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEJ5dGVzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEJ5dGVzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0RPVUJMRV8zX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xEb3VibGUzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBCb29sRG91YmxlM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xEb3VibGUzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xEb3VibGUzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRG91YmxlM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEJvb2xEb3VibGUzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0VOVU1fNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEVudW00XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sRW51bTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xFbnVtNF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBCb29sRW51bTRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwQm9vbEVudW00VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xFbnVtNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBCb29sRW51bTRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfRklYRUQzMl81X0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xGaXhlZDMyNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sRml4ZWQ2NDZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfRkxPQVRfN19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwQm9vbEZsb2F0N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sRmxvYXQ3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZsb2F0N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZsb2F0N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0lOVDMyXzhfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEludDMyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sSW50NjQ5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEludDY0OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDY0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX01FU1NBR0VfMTBfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9TRklYRUQzMl8xMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sU2ZpeGVkNjQxMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9TSU5UMzJfMTNfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTaW50MzIxM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU2ludDMyMTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50MzIxM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTaW50MzIxM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0lOVDY0XzE0X0ZJRUxEX05VTUJFUiA9IDE0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDY0MTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50NjQxNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9TVFJJTkdfMTVfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEJvb2xTdHJpbmcxNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTdHJpbmcxNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU3RyaW5nMTUoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9VSU5UMzJfMTZfRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbFVpbnQzMjE2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sVWludDMyMTZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfVUlOVDY0XzE3X0ZJRUxEX05VTUJFUiA9IDE3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sVWludDY0MTdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDY0MTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sVWludDY0MTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDY0MTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEZpeGVkMzJCb29sMThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQm9vbDE4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfQllURVNfMTlfRklFTERfTlVNQkVSID0gMTk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJCeXRlczE5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0RPVUJMRV8yMF9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfRU5VTV8yMV9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVEMzJfMjJfRklFTERfTlVNQkVSID0gMjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVENjRfMjNfRklFTERfTlVNQkVSID0gMjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9GTE9BVF8yNF9GSUVMRF9OVU1CRVIgPSAyNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGbG9hdDI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9JTlQzMl8yNV9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9JTlQ2NF8yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMySW50NjQyNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50NjQyNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfTUVTU0FHRV8yN19GSUVMRF9OVU1CRVIgPSAyNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfU0ZJWEVEMzJfMjhfRklFTERfTlVNQkVSID0gMjg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfU0ZJWEVENjRfMjlfRklFTERfTlVNQkVSID0gMjk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NJTlQzMl8zMF9GSUVMRF9OVU1CRVIgPSAzMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NJTlQ2NF8zMV9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSID0gMzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1VJTlQzMl8zM19GSUVMRF9OVU1CRVIgPSAzMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1VJTlQ2NF8zNF9GSUVMRF9OVU1CRVIgPSAzNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9CT09MXzM1X0ZJRUxEX05VTUJFUiA9IDM1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBGaXhlZDY0Qm9vbDM1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0JZVEVTXzM2X0ZJRUxEX05VTUJFUiA9IDM2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRE9VQkxFXzM3X0ZJRUxEX05VTUJFUiA9IDM3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUiA9IDM5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRklYRUQ2NF80MF9GSUVMRF9OVU1CRVIgPSA0MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9GTE9BVF80MV9GSUVMRF9OVU1CRVIgPSA0MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSID0gNDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0lOVDY0XzQzX0ZJRUxEX05VTUJFUiA9IDQzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0SW50NjQ0M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0SW50NjQ0M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0SW50NjQ0M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfTUVTU0FHRV80NF9GSUVMRF9OVU1CRVIgPSA0NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NGSVhFRDMyXzQ1X0ZJRUxEX05VTUJFUiA9IDQ1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQ2NF80Nl9GSUVMRF9OVU1CRVIgPSA0NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NJTlQzMl80N19GSUVMRF9OVU1CRVIgPSA0NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UNjRfNDhfRklFTERfTlVNQkVSID0gNDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50NjQ0OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NUUklOR180OV9GSUVMRF9OVU1CRVIgPSA0OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1VJTlQzMl81MF9GSUVMRF9OVU1CRVIgPSA1MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0VWludDMyNTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UNjRfNTFfRklFTERfTlVNQkVSID0gNTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9CT09MXzUyX0ZJRUxEX05VTUJFUiA9IDUyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkJvb2w1MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQm9vbDUyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyQm9vbDUyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJvb2w1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkJvb2w1MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfQllURVNfNTNfRklFTERfTlVNQkVSID0gNTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyQnl0ZXM1M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCeXRlczUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCeXRlczUzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQnl0ZXM1MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0RPVUJMRV81NF9GSUVMRF9OVU1CRVIgPSA1NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJEb3VibGU1NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkRvdWJsZTU0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkRvdWJsZTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJEb3VibGU1NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJEb3VibGU1NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfRU5VTV81NV9GSUVMRF9OVU1CRVIgPSA1NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkVudW01NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDMyRW51bTU1TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDMyRW51bTU1TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0ZJWEVEMzJfNTZfRklFTERfTlVNQkVSID0gNTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRml4ZWQzMjU2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0ZJWEVENjRfNTdfRklFTERfTlVNQkVSID0gNTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9GTE9BVF81OF9GSUVMRF9OVU1CRVIgPSA1ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJGbG9hdDU4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkZsb2F0NThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9JTlQzMl81OV9GSUVMRF9OVU1CRVIgPSA1OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDMyNTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9JTlQ2NF82MF9GSUVMRF9OVU1CRVIgPSA2MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMySW50NjQ2MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfTUVTU0FHRV82MV9GSUVMRF9OVU1CRVIgPSA2MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyTWVzc2FnZTYxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyTWVzc2FnZTYxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVEMzJfNjJfRklFTERfTlVNQkVSID0gNjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVENjRfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1NJTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1NJTlQ2NF82NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TVFJJTkdfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwSW50MzJTdHJpbmc2Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTdHJpbmc2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1VJTlQzMl82N19GSUVMRF9OVU1CRVIgPSA2NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1VJTlQ2NF82OF9GSUVMRF9OVU1CRVIgPSA2ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9CT09MXzY5X0ZJRUxEX05VTUJFUiA9IDY5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEJvb2w2OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRCb29sNjlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0JZVEVTXzcwX0ZJRUxEX05VTUJFUiA9IDcwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRCeXRlczcwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRE9VQkxFXzcxX0ZJRUxEX05VTUJFUiA9IDcxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjREb3VibGU3MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRU5VTV83Ml9GSUVMRF9OVU1CRVIgPSA3MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEVudW03MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRFbnVtNzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50NjRFbnVtNzJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9GSVhFRDMyXzczX0ZJRUxEX05VTUJFUiA9IDczOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0Rml4ZWQzMjczXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRklYRUQ2NF83NF9GSUVMRF9OVU1CRVIgPSA3NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVIgPSA3NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRGbG9hdDc1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZsb2F0NzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfSU5UMzJfNzZfRklFTERfTlVNQkVSID0gNzY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRJbnQzMjc2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDMyNzZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0lOVDY0Xzc3X0ZJRUxEX05VTUJFUiA9IDc3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0SW50NjQ3N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfTUVTU0FHRV83OF9GSUVMRF9OVU1CRVIgPSA3ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBmaWVsZE1hcEludDY0TWVzc2FnZTc4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRNZXNzYWdlNzgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NGSVhFRDMyXzc5X0ZJRUxEX05VTUJFUiA9IDc5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TRklYRUQ2NF84MF9GSUVMRF9OVU1CRVIgPSA4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NJTlQzMl84MV9GSUVMRF9OVU1CRVIgPSA4MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDMyODFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50MzI4MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TSU5UNjRfODJfRklFTERfTlVNQkVSID0gODI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVIgPSA4MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1VJTlQzMl84NF9GSUVMRF9OVU1CRVIgPSA4NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDMyODRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFVpbnQzMjg0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50MzI4NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9VSU5UNjRfODVfRklFTERfTlVNQkVSID0gODU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0JPT0xfODZfRklFTERfTlVNQkVSID0gODY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9CWVRFU184N19GSUVMRF9OVU1CRVIgPSA4NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRE9VQkxFXzg4X0ZJRUxEX05VTUJFUiA9IDg4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUiA9IDg5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQzMl85MF9GSUVMRF9OVU1CRVIgPSA5MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0ZMT0FUXzkyX0ZJRUxEX05VTUJFUiA9IDkyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0lOVDMyXzkzX0ZJRUxEX05VTUJFUiA9IDkzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUiA9IDk0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9NRVNTQUdFXzk1X0ZJRUxEX05VTUJFUiA9IDk1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQzMl85Nl9GSUVMRF9OVU1CRVIgPSA5NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQ2NF85N19GSUVMRF9OVU1CRVIgPSA5NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDMyXzk4X0ZJRUxEX05VTUJFUiA9IDk4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDY0Xzk5X0ZJRUxEX05VTUJFUiA9IDk5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX1NUUklOR18xMDBfRklFTERfTlVNQkVSID0gMTAwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfVUlOVDMyXzEwMV9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfVUlOVDY0XzEwMl9GSUVMRF9OVU1CRVIgPSAxMDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X0JPT0xfMTAzX0ZJRUxEX05VTUJFUiA9IDEwMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfQllURVNfMTA0X0ZJRUxEX05VTUJFUiA9IDEwNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9ET1VCTEVfMTA1X0ZJRUxEX05VTUJFUiA9IDEwNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9FTlVNXzEwNl9GSUVMRF9OVU1CRVIgPSAxMDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X0ZJWEVEMzJfMTA3X0ZJRUxEX05VTUJFUiA9IDEwNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVIgPSAxMDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X0ZMT0FUXzEwOV9GSUVMRF9OVU1CRVIgPSAxMDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9JTlQzMl8xMTBfRklFTERfTlVNQkVSID0gMTEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUiA9IDExMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9NRVNTQUdFXzExMl9GSUVMRF9OVU1CRVIgPSAxMTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfU0ZJWEVEMzJfMTEzX0ZJRUxEX05VTUJFUiA9IDExMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDY0XzExNF9GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfU0lOVDMyXzExNV9GSUVMRF9OVU1CRVIgPSAxMTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NJTlQ2NF8xMTZfRklFTERfTlVNQkVSID0gMTE2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfU1RSSU5HXzExN19GSUVMRF9OVU1CRVIgPSAxMTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfVUlOVDMyXzExOF9GSUVMRF9OVU1CRVIgPSAxMTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1VJTlQ2NF8xMTlfRklFTERfTlVNQkVSID0gMTE5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUiA9IDEyMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJCb29sMTIwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9CWVRFU18xMjFfRklFTERfTlVNQkVSID0gMTIxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJCeXRlczEyMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRE9VQkxFXzEyMl9GSUVMRF9OVU1CRVIgPSAxMjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9FTlVNXzEyM19GSUVMRF9OVU1CRVIgPSAxMjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRW51bTEyM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRklYRUQzMl8xMjRfRklFTERfTlVNQkVSID0gMTI0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRklYRUQ2NF8xMjVfRklFTERfTlVNQkVSID0gMTI1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0ZMT0FUXzEyNl9GSUVMRF9OVU1CRVIgPSAxMjY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGbG9hdDEyNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0lOVDMyXzEyN19GSUVMRF9OVU1CRVIgPSAxMjc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0lOVDY0XzEyOF9GSUVMRF9OVU1CRVIgPSAxMjg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50NjQxMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9NRVNTQUdFXzEyOV9GSUVMRF9OVU1CRVIgPSAxMjk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9TRklYRUQzMl8xMzBfRklFTERfTlVNQkVSID0gMTMwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9TRklYRUQ2NF8xMzFfRklFTERfTlVNQkVSID0gMTMxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU0lOVDMyXzEzMl9GSUVMRF9OVU1CRVIgPSAxMzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU0lOVDY0XzEzM19GSUVMRF9OVU1CRVIgPSAxMzM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSID0gMTM0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfVUlOVDMyXzEzNV9GSUVMRF9OVU1CRVIgPSAxMzU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfVUlOVDY0XzEzNl9GSUVMRF9OVU1CRVIgPSAxMzY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0JPT0xfMTM3X0ZJRUxEX05VTUJFUiA9IDEzNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTaW50NjRCb29sMTM3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfQllURVNfMTM4X0ZJRUxEX05VTUJFUiA9IDEzODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCeXRlczEzOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9ET1VCTEVfMTM5X0ZJRUxEX05VTUJFUiA9IDEzOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVIgPSAxNDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRFbnVtMTQwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUiA9IDE0MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9GSVhFRDY0XzE0Ml9GSUVMRF9OVU1CRVIgPSAxNDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0ZMT0FUXzE0M19GSUVMRF9OVU1CRVIgPSAxNDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSID0gMTQ0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfSU5UNjRfMTQ1X0ZJRUxEX05VTUJFUiA9IDE0NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQ2NDE0NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9NRVNTQUdFXzE0Nl9GSUVMRF9OVU1CRVIgPSAxNDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU0ZJWEVEMzJfMTQ3X0ZJRUxEX05VTUJFUiA9IDE0NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDY0XzE0OF9GSUVMRF9OVU1CRVIgPSAxNDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU0lOVDMyXzE0OV9GSUVMRF9OVU1CRVIgPSAxNDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NJTlQ2NF8xNTBfRklFTERfTlVNQkVSID0gMTUwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU1RSSU5HXzE1MV9GSUVMRF9OVU1CRVIgPSAxNTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfVUlOVDMyXzE1Ml9GSUVMRF9OVU1CRVIgPSAxNTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1VJTlQ2NF8xNTNfRklFTERfTlVNQkVSID0gMTUzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfQk9PTF8xNTRfRklFTERfTlVNQkVSID0gMTU0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfQllURVNfMTU1X0ZJRUxEX05VTUJFUiA9IDE1NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRE9VQkxFXzE1Nl9GSUVMRF9OVU1CRVIgPSAxNTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0VOVU1fMTU3X0ZJRUxEX05VTUJFUiA9IDE1NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0ZJWEVEMzJfMTU4X0ZJRUxEX05VTUJFUiA9IDE1ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRklYRUQ2NF8xNTlfRklFTERfTlVNQkVSID0gMTU5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRkxPQVRfMTYwX0ZJRUxEX05VTUJFUiA9IDE2MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTdHJpbmdGbG9hdDE2MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGbG9hdDE2MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19JTlQzMl8xNjFfRklFTERfTlVNQkVSID0gMTYxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0lOVDY0XzE2Ml9GSUVMRF9OVU1CRVIgPSAxNjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50NjQxNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX01FU1NBR0VfMTYzX0ZJRUxEX05VTUJFUiA9IDE2MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVEMzJfMTY0X0ZJRUxEX05VTUJFUiA9IDE2NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSID0gMTY1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TSU5UMzJfMTY2X0ZJRUxEX05VTUJFUiA9IDE2NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NJTlQ2NF8xNjdfRklFTERfTlVNQkVSID0gMTY3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NUUklOR18xNjhfRklFTERfTlVNQkVSID0gMTY4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19VSU5UMzJfMTY5X0ZJRUxEX05VTUJFUiA9IDE2OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1VJTlQ2NF8xNzBfRklFTERfTlVNQkVSID0gMTcwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUiA9IDE3MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJCb29sMTcxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9CWVRFU18xNzJfRklFTERfTlVNQkVSID0gMTcyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJCeXRlczE3MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCeXRlczE3Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRE9VQkxFXzE3M19GSUVMRF9OVU1CRVIgPSAxNzM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRG91YmxlMTczXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRG91YmxlMTczKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9FTlVNXzE3NF9GSUVMRF9OVU1CRVIgPSAxNzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRW51bTE3NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRklYRUQzMl8xNzVfRklFTERfTlVNQkVSID0gMTc1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRklYRUQ2NF8xNzZfRklFTERfTlVNQkVSID0gMTc2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0ZMT0FUXzE3N19GSUVMRF9OVU1CRVIgPSAxNzc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBVaW50MzJGbG9hdDE3N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0lOVDMyXzE3OF9GSUVMRF9OVU1CRVIgPSAxNzg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkludDMyMTc4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0lOVDY0XzE3OV9GSUVMRF9OVU1CRVIgPSAxNzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50NjQxNzlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMySW50NjQxNzlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9NRVNTQUdFXzE4MF9GSUVMRF9OVU1CRVIgPSAxODA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9TRklYRUQzMl8xODFfRklFTERfTlVNQkVSID0gMTgxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9TRklYRUQ2NF8xODJfRklFTERfTlVNQkVSID0gMTgyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU0lOVDMyXzE4M19GSUVMRF9OVU1CRVIgPSAxODM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDMyMTgzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50MzIxODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU0lOVDY0XzE4NF9GSUVMRF9OVU1CRVIgPSAxODQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSID0gMTg1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfVUlOVDMyXzE4Nl9GSUVMRF9OVU1CRVIgPSAxODY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50MzIxODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfVUlOVDY0XzE4N19GSUVMRF9OVU1CRVIgPSAxODc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDY0MTg3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0JPT0xfMTg4X0ZJRUxEX05VTUJFUiA9IDE4ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50NjRCb29sMTg4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfQllURVNfMTg5X0ZJRUxEX05VTUJFUiA9IDE4OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9ET1VCTEVfMTkwX0ZJRUxEX05VTUJFUiA9IDE5MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVIgPSAxOTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUiA9IDE5MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9GSVhFRDY0XzE5M19GSUVMRF9OVU1CRVIgPSAxOTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0ZMT0FUXzE5NF9GSUVMRF9OVU1CRVIgPSAxOTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSID0gMTk1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0SW50MzIxOTVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50MzIxOTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50MzIxOTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfSU5UNjRfMTk2X0ZJRUxEX05VTUJFUiA9IDE5NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQ2NDE5NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9NRVNTQUdFXzE5N19GSUVMRF9OVU1CRVIgPSAxOTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU0ZJWEVEMzJfMTk4X0ZJRUxEX05VTUJFUiA9IDE5ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDY0XzE5OV9GSUVMRF9OVU1CRVIgPSAxOTk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU0lOVDMyXzIwMF9GSUVMRF9OVU1CRVIgPSAyMDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NJTlQ2NF8yMDFfRklFTERfTlVNQkVSID0gMjAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRTaW50NjQyMDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50NjQyMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU1RSSU5HXzIwMl9GSUVMRF9OVU1CRVIgPSAyMDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfVUlOVDMyXzIwM19GSUVMRF9OVU1CRVIgPSAyMDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1VJTlQ2NF8yMDRfRklFTERfTlVNQkVSID0gMjA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGl0ZW0gOiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGl0ZW0gOiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGl0ZW0gOiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGl0ZW0gOiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGl0ZW0gOiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLAogICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLAogICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLAogICAgICAgICAgRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLAogICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLAogICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGbG9hdDQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDU5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLAogICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLAogICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDY2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTAwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTU4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTY3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTczKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxODApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTg4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBmaWVsZE1hcEJvb2xCb29sMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXyA9IEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZmllbGRNYXBCb29sQnl0ZXMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfXyA9IEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGZpZWxkTWFwQm9vbERvdWJsZTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sRW51bTRfXyA9IEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBmaWVsZE1hcEJvb2xFbnVtNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fID0gRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18gPSBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgZmllbGRNYXBCb29sRml4ZWQ2NDZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3X18gPSBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGZpZWxkTWFwQm9vbEZsb2F0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sSW50MzI4X18gPSBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIGZpZWxkTWFwQm9vbEludDMyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18gPSBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGZpZWxkTWFwQm9vbEludDY0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfXyA9IEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXyA9IEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExLCBmaWVsZE1hcEJvb2xTZml4ZWQzMjExX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fID0gRmllbGRNYXBCb29sU2ZpeGVkNjQxMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIsIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sU2ludDMyMTNfXyA9IEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMywgZmllbGRNYXBCb29sU2ludDMyMTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sU2ludDY0MTRfXyA9IEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNCwgZmllbGRNYXBCb29sU2ludDY0MTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1X18gPSBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUsIGZpZWxkTWFwQm9vbFN0cmluZzE1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18gPSBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTYsIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18gPSBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcsIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfXyA9IEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fID0gRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTksIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18gPSBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAsIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXyA9IEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjEsIGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyX18gPSBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIyLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM19fID0gRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMywgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18gPSBGaWVsZE1hcEZpeGVkMzJGbG9hdDI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNCwgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXyA9IEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI1LCBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fID0gRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjYsIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18gPSBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI3LCBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4X18gPSBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyOCwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfXyA9IEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI5LCBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18gPSBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMzAsIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18gPSBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMzEsIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fID0gRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMyLCBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fID0gRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMzLCBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fID0gRmllbGRNYXBGaXhlZDMyVWludDY0MzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM0LCBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18gPSBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM1LCBmaWVsZE1hcEZpeGVkNjRCb29sMzVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfXyA9IEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM2LCBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fID0gRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM3LCBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4X18gPSBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM4LCBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fID0gRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzOSwgZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXyA9IEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDAsIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV9fID0gRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDEsIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyX18gPSBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0MiwgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfXyA9IEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQzLCBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fID0gRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NCwgZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fID0gRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDUsIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18gPSBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NiwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fID0gRmllbGRNYXBGaXhlZDY0U2ludDMyNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ3LCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fID0gRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ4LCBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyA9IEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MCwgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MSwgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEludDMyQm9vbDUyX18gPSBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MiwgZmllbGRNYXBJbnQzMkJvb2w1Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTMsIGZpZWxkTWFwSW50MzJCeXRlczUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18gPSBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU0LCBmaWVsZE1hcEludDMyRG91YmxlNTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyRW51bTU1X18gPSBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1NSwgZmllbGRNYXBJbnQzMkVudW01NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXyA9IEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU2LCBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fID0gRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTcsIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF9fID0gRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU4LCBmaWVsZE1hcEludDMyRmxvYXQ1OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fID0gRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU5LCBmaWVsZE1hcEludDMySW50MzI1OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF9fID0gRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYwLCBmaWVsZE1hcEludDMySW50NjQ2MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fID0gRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjEsIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXyA9IEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MiwgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXyA9IEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MywgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fID0gRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NCwgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMyU2ludDY0NjVfXyA9IEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjUsIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl9fID0gRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NiwgZmllbGRNYXBJbnQzMlN0cmluZzY2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfXyA9IEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjcsIGZpZWxkTWFwSW50MzJVaW50MzI2N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18gPSBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY4LCBmaWVsZE1hcEludDMyVWludDY0NjhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5X18gPSBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2OSwgZmllbGRNYXBJbnQ2NEJvb2w2OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50NjRCeXRlczcwX18gPSBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzAsIGZpZWxkTWFwSW50NjRCeXRlczcwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18gPSBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcxLCBmaWVsZE1hcEludDY0RG91YmxlNzFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyX18gPSBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3MiwgZmllbGRNYXBJbnQ2NEVudW03Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXyA9IEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDczLCBmaWVsZE1hcEludDY0Rml4ZWQzMjczX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fID0gRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzQsIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEludDY0RmxvYXQ3NV9fID0gRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc1LCBmaWVsZE1hcEludDY0RmxvYXQ3NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl9fID0gRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc2LCBmaWVsZE1hcEludDY0SW50MzI3Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N19fID0gRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc3LCBmaWVsZE1hcEludDY0SW50NjQ3N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF9fID0gRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzgsIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXyA9IEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3OSwgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfXyA9IEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4MCwgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRTaW50MzI4MV9fID0gRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4MSwgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfXyA9IEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODIsIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fID0gRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4MywgZmllbGRNYXBJbnQ2NFN0cmluZzgzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfXyA9IEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODQsIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1X18gPSBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg1LCBmaWVsZE1hcEludDY0VWludDY0ODVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2X18gPSBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4NiwgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18gPSBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODcsIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4X18gPSBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg4LCBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRW51bTg5X18gPSBGaWVsZE1hcFNmaXhlZDMyRW51bTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4OSwgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfXyA9IEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkwLCBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV9fID0gRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTEsIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fID0gRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkyLCBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fID0gRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkzLCBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fID0gRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDk0LCBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fID0gRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTUsIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NiwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NywgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fID0gRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5OCwgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTksIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18gPSBGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDAsIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDEsIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDIsIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXyA9IEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDMsIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fID0gRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDQsIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDUsIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDYsIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18gPSBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTA3LCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fID0gRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOCwgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18gPSBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOSwgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyA9IEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEwLCBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fID0gRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTEsIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18gPSBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEyLCBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18gPSBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExMywgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE0LCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1X18gPSBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTUsIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2X18gPSBGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTYsIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN19fID0gRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE3LCBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF9fID0gRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE4LCBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV9fID0gRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE5LCBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXyA9IEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIwLCBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfXyA9IEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyMSwgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXyA9IEZpZWxkTWFwU2ludDMyRG91YmxlMTIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjIsIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXyA9IEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIzLCBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fID0gRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjQsIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18gPSBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNSwgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2X18gPSBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjYsIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMkludDMyMTI3X18gPSBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjcsIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4X18gPSBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjgsIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5X18gPSBGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyOSwgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fID0gRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMwLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fID0gRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMxLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyX18gPSBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMyLCBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fID0gRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMywgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18gPSBGaWVsZE1hcFNpbnQzMlN0cmluZzEzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM0LCBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fID0gRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzNSwgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJVaW50NjQxMzZfXyA9IEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzYsIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyA9IEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM3LCBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXyA9IEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzOCwgZmllbGRNYXBTaW50NjRCeXRlczEzOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTaW50NjREb3VibGUxMzlfXyA9IEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzksIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXyA9IEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQwLCBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fID0gRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDEsIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18gPSBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0MiwgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18gPSBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDMsIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18gPSBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDQsIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18gPSBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDUsIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18gPSBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0NiwgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fID0gRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ3LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fID0gRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ4LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5X18gPSBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ5LCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fID0gRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MCwgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18gPSBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUxLCBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MiwgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfXyA9IEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTMsIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18gPSBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NCwgZmllbGRNYXBTdHJpbmdCb29sMTU0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTU1LCBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfXyA9IEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTYsIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18gPSBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NywgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OCwgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OSwgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fID0gRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTYwLCBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXyA9IEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2MSwgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18gPSBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjIsIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fID0gRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjMsIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0X18gPSBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjQsIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV9fID0gRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY1LCBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fID0gRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2NiwgZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18gPSBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY3LCBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18gPSBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY4LCBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXyA9IEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjksIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fID0gRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3MCwgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fID0gRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzEsIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml9fID0gRmllbGRNYXBVaW50MzJCeXRlczE3MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcyLCBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fID0gRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3MywgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF9fID0gRmllbGRNYXBVaW50MzJFbnVtMTc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzQsIGZpZWxkTWFwVWludDMyRW51bTE3NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18gPSBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3NSwgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXyA9IEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc2LCBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfXyA9IEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3NywgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfXyA9IEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3OCwgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDMySW50NjQxNzlfXyA9IEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3OSwgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXyA9IEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgwLCBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18gPSBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODEsIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18gPSBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODIsIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXyA9IEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODMsIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18gPSBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg0LCBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXyA9IEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODUsIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2X18gPSBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg2LCBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fID0gRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4NywgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwVWludDY0Qm9vbDE4OF9fID0gRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODgsIGZpZWxkTWFwVWludDY0Qm9vbDE4OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fID0gRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg5LCBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fID0gRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5MCwgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV9fID0gRmllbGRNYXBVaW50NjRFbnVtMTkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTEsIGZpZWxkTWFwVWludDY0RW51bTE5MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18gPSBGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5MiwgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXyA9IEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTkzLCBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXyA9IEZpZWxkTWFwVWludDY0RmxvYXQxOTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5NCwgZmllbGRNYXBVaW50NjRGbG9hdDE5NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXyA9IEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5NSwgZmllbGRNYXBVaW50NjRJbnQzMjE5NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXyA9IEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5NiwgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyA9IEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTk3LCBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTgsIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXyA9IEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDAsIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAxLCBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDIsIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzX18gPSBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAzLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fID0gRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNCwgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQk9PTF8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQllURVNfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRE9VQkxFXzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRU5VTV80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9GSVhFRDMyXzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZMT0FUXzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfSU5UMzJfOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NGSVhFRDMyXzExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0lOVDMyXzEzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9TSU5UNjRfMTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NUUklOR18xNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfVUlOVDMyXzE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9VSU5UNjRfMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9ET1VCTEVfMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9FTlVNXzIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVEMzJfMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRklYRUQ2NF8yM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRkxPQVRfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9JTlQzMl8yNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0lOVDY0XzI2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TRklYRUQzMl8yOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDY0XzI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NJTlQzMl8zMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfU0lOVDY0XzMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1VJTlQzMl8zM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfVUlOVDY0XzM0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQk9PTF8zNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQllURVNfMzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRE9VQkxFXzM3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZJWEVENjRfNDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZMT0FUXzQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9JTlQ2NF80M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfTUVTU0FHRV80NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU0ZJWEVEMzJfNDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQ2NF80Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UMzJfNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1NJTlQ2NF80OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU1RSSU5HXzQ5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UMzJfNTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1VJTlQ2NF81MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQk9PTF81Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQllURVNfNTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRE9VQkxFXzU0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRU5VTV81NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9GSVhFRDMyXzU2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZJWEVENjRfNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZMT0FUXzU4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfSU5UMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9JTlQ2NF82MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfTUVTU0FHRV82MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVEMzJfNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TRklYRUQ2NF82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1NJTlQ2NF82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU1RSSU5HXzY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9VSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1VJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JPT0xfNjlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JZVEVTXzcwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0RPVUJMRV83MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0VOVU1fNzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfRklYRUQzMl83M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GSVhFRDY0Xzc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0lOVDMyXzc2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfSU5UNjRfNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X01FU1NBR0VfNzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NGSVhFRDMyXzc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVENjRfODBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0lOVDMyXzgxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9TSU5UNjRfODJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfVUlOVDMyXzg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9VSU5UNjRfODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CT09MXzg2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CWVRFU184N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9ET1VCTEVfODhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0ZJWEVEMzJfOTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRkxPQVRfOTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9JTlQzMl85M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9NRVNTQUdFXzk1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQzMl85Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NGSVhFRDY0Xzk3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NJTlQzMl85OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDY0Xzk5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU1RSSU5HXzEwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9VSU5UMzJfMTAxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1VJTlQ2NF8xMDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JPT0xfMTAzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JZVEVTXzEwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0RPVUJMRV8xMDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0VOVU1fMTA2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfRklYRUQzMl8xMDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GTE9BVF8xMDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0lOVDMyXzExMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X01FU1NBR0VfMTEyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDMyXzExM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0ZJWEVENjRfMTE0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0lOVDMyXzExNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UNjRfMTE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NUUklOR18xMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfVUlOVDMyXzExOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UNjRfMTE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0RPVUJMRV8xMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0VOVU1fMTIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfRklYRUQzMl8xMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GSVhFRDY0XzEyNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GTE9BVF8xMjZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0lOVDMyXzEyN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfSU5UNjRfMTI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NGSVhFRDMyXzEzMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVENjRfMTMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0lOVDMyXzEzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9TSU5UNjRfMTMzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfVUlOVDMyXzEzNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9VSU5UNjRfMTM2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CT09MXzEzN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CWVRFU18xMzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9ET1VCTEVfMTM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRklYRUQ2NF8xNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRkxPQVRfMTQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0lOVDY0XzE0NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9NRVNTQUdFXzE0Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TRklYRUQzMl8xNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDY0XzE0OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NJTlQzMl8xNDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfU0lOVDY0XzE1MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TVFJJTkdfMTUxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1VJTlQzMl8xNTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfVUlOVDY0XzE1M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQk9PTF8xNTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQllURVNfMTU1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRE9VQkxFXzE1Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRU5VTV8xNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19GSVhFRDMyXzE1OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZJWEVENjRfMTU5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZMT0FUXzE2MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfSU5UMzJfMTYxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19JTlQ2NF8xNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfTUVTU0FHRV8xNjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVEMzJfMTY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TSU5UMzJfMTY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1NJTlQ2NF8xNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU1RSSU5HXzE2OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19VSU5UMzJfMTY5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1VJTlQ2NF8xNzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0RPVUJMRV8xNzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0VOVU1fMTc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfRklYRUQzMl8xNzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GSVhFRDY0XzE3Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GTE9BVF8xNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0lOVDMyXzE3OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfSU5UNjRfMTc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NGSVhFRDMyXzE4MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVENjRfMTgyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0lOVDMyXzE4M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9TSU5UNjRfMTg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfVUlOVDMyXzE4Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9VSU5UNjRfMTg3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CT09MXzE4OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CWVRFU18xODlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9ET1VCTEVfMTkwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRklYRUQ2NF8xOTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRkxPQVRfMTk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0lOVDY0XzE5Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9NRVNTQUdFXzE5N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TRklYRUQzMl8xOThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDY0XzE5OV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NJTlQzMl8yMDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfU0lOVDY0XzIwMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TVFJJTkdfMjAyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1VJTlQzMl8yMDNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfVUlOVDY0XzIwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpOwogICAgICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgICAgICAgIGNhc2UgMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCk7CiAgICAgICAgICBjYXNlIDE4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICAgIGNhc2UgMTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgICAgICAgIGNhc2UgMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCk7CiAgICAgICAgICBjYXNlIDIxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICAgIGNhc2UgMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgICAgICAgY2FzZSAyMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCk7CiAgICAgICAgICBjYXNlIDI0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgICBjYXNlIDI1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCk7CiAgICAgICAgICBjYXNlIDI2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCk7CiAgICAgICAgICBjYXNlIDI3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICAgIGNhc2UgMjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgICAgICAgIGNhc2UgMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKTsKICAgICAgICAgIGNhc2UgMzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgICBjYXNlIDMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpOwogICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKTsKICAgICAgICAgIGNhc2UgMzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgICBjYXNlIDM0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpOwogICAgICAgICAgY2FzZSAzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCk7CiAgICAgICAgICBjYXNlIDM2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICBjYXNlIDM3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpOwogICAgICAgICAgY2FzZSAzODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCk7CiAgICAgICAgICBjYXNlIDM5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICAgIGNhc2UgNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgY2FzZSA0MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpOwogICAgICAgICAgY2FzZSA0MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgICAgY2FzZSA0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgICAgICAgY2FzZSA0NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCk7CiAgICAgICAgICBjYXNlIDQ1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICBjYXNlIDQ2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpOwogICAgICAgICAgY2FzZSA0ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIGNhc2UgNDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAgICAgICBjYXNlIDUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpOwogICAgICAgICAgY2FzZSA1MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIGNhc2UgNTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgICAgICAgIGNhc2UgNTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCk7CiAgICAgICAgICBjYXNlIDU0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICAgIGNhc2UgNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKTsKICAgICAgICAgIGNhc2UgNTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKTsKICAgICAgICAgIGNhc2UgNTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICAgIGNhc2UgNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAgICAgICBjYXNlIDU5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpOwogICAgICAgICAgY2FzZSA2MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIGNhc2UgNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKTsKICAgICAgICAgIGNhc2UgNjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCk7CiAgICAgICAgICBjYXNlIDYzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgICAgY2FzZSA2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCk7CiAgICAgICAgICBjYXNlIDY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKTsKICAgICAgICAgIGNhc2UgNjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgICAgY2FzZSA2NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICBjYXNlIDY4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKTsKICAgICAgICAgIGNhc2UgNjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIGNhc2UgNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAgICAgICBjYXNlIDcxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKTsKICAgICAgICAgIGNhc2UgNzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIGNhc2UgNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKTsKICAgICAgICAgIGNhc2UgNzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgICBjYXNlIDc2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgY2FzZSA3NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKTsKICAgICAgICAgIGNhc2UgNzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICAgIGNhc2UgNzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCk7CiAgICAgICAgICBjYXNlIDgwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgICAgICAgY2FzZSA4MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICBjYXNlIDgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgICAgICAgIGNhc2UgODM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpOwogICAgICAgICAgY2FzZSA4NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICBjYXNlIDg1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKTsKICAgICAgICAgIGNhc2UgODY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgICAgICAgIGNhc2UgODc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgICBjYXNlIDg4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKTsKICAgICAgICAgIGNhc2UgODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgICAgICAgIGNhc2UgOTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIGNhc2UgOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIGNhc2UgOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCk7CiAgICAgICAgICBjYXNlIDkzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgY2FzZSA5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKTsKICAgICAgICAgIGNhc2UgOTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKTsKICAgICAgICAgIGNhc2UgOTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgICBjYXNlIDk3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpOwogICAgICAgICAgY2FzZSA5ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAgICAgICBjYXNlIDk5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICAgIGNhc2UgMTAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAgICAgICBjYXNlIDEwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpOwogICAgICAgICAgY2FzZSAxMDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICAgIGNhc2UgMTAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpOwogICAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgICAgICAgY2FzZSAxMDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICAgIGNhc2UgMTA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpOwogICAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAgICAgICBjYXNlIDEwODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICAgIGNhc2UgMTA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKTsKICAgICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgICAgICAgIGNhc2UgMTExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpOwogICAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpOwogICAgICAgICAgY2FzZSAxMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgICAgY2FzZSAxMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKTsKICAgICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCk7CiAgICAgICAgICBjYXNlIDExNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgICAgY2FzZSAxMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKTsKICAgICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCk7CiAgICAgICAgICBjYXNlIDEyMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgICBjYXNlIDEyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCk7CiAgICAgICAgICBjYXNlIDEyMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgICBjYXNlIDEyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAgICAgICBjYXNlIDEyNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCk7CiAgICAgICAgICBjYXNlIDEyNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgICAgY2FzZSAxMjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKTsKICAgICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCk7CiAgICAgICAgICBjYXNlIDEyOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgICBjYXNlIDEzMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKTsKICAgICAgICAgIGNhc2UgMTMyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgICAgY2FzZSAxMzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCk7CiAgICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgICAgICAgIGNhc2UgMTM1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgICAgY2FzZSAxMzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCk7CiAgICAgICAgICBjYXNlIDEzODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgICAgY2FzZSAxMzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCk7CiAgICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCk7CiAgICAgICAgICBjYXNlIDE0MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgICBjYXNlIDE0MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCk7CiAgICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpOwogICAgICAgICAgY2FzZSAxNDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICAgIGNhc2UgMTQ1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCk7CiAgICAgICAgICBjYXNlIDE0NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgICAgY2FzZSAxNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKTsKICAgICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpOwogICAgICAgICAgY2FzZSAxNTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgICBjYXNlIDE1MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpOwogICAgICAgICAgY2FzZSAxNTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgICBjYXNlIDE1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCk7CiAgICAgICAgICBjYXNlIDE1NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpOwogICAgICAgICAgY2FzZSAxNTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgICBjYXNlIDE1NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCk7CiAgICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCk7CiAgICAgICAgICBjYXNlIDE1OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgICBjYXNlIDE2MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpOwogICAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgICAgICAgIGNhc2UgMTYyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgICBjYXNlIDE2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCk7CiAgICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpOwogICAgICAgICAgY2FzZSAxNjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIGNhc2UgMTY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCk7CiAgICAgICAgICBjYXNlIDE2ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICAgIGNhc2UgMTY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCk7CiAgICAgICAgICBjYXNlIDE3MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICBjYXNlIDE3MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCk7CiAgICAgICAgICBjYXNlIDE3NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICBjYXNlIDE3NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAgICAgICBjYXNlIDE3NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgICAgY2FzZSAxNzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCk7CiAgICAgICAgICBjYXNlIDE4MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgICBjYXNlIDE4MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpOwogICAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgICAgICAgIGNhc2UgMTgzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgY2FzZSAxODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAgICAgICBjYXNlIDE4NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKTsKICAgICAgICAgIGNhc2UgMTg2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgY2FzZSAxODc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCk7CiAgICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAgICAgICBjYXNlIDE4OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgICAgY2FzZSAxOTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAgICAgICBjYXNlIDE5MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAgICAgICBjYXNlIDE5MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICBjYXNlIDE5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgICAgICAgY2FzZSAxOTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICAgIGNhc2UgMTk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCk7CiAgICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCk7CiAgICAgICAgICBjYXNlIDE5ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgICAgY2FzZSAxOTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgICAgICAgY2FzZSAyMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgICBjYXNlIDIwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKTsKICAgICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpOwogICAgICAgICAgY2FzZSAyMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICAgIGNhc2UgMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCk7CiAgICAgICAgICBjYXNlIDEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCk7CiAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgICAgICAgIGNhc2UgMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgICAgY2FzZSAxODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpOwogICAgICAgICAgY2FzZSAxOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgICAgICAgIGNhc2UgMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgICAgY2FzZSAyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpOwogICAgICAgICAgY2FzZSAyMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgICAgICAgY2FzZSAyMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKTsKICAgICAgICAgIGNhc2UgMjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCk7CiAgICAgICAgICBjYXNlIDI2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgICAgY2FzZSAyNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpOwogICAgICAgICAgY2FzZSAyODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgICAgICAgIGNhc2UgMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgICBjYXNlIDMwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKTsKICAgICAgICAgIGNhc2UgMzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpOwogICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgICBjYXNlIDMzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgICAgICAgIGNhc2UgMzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpOwogICAgICAgICAgY2FzZSAzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgY2FzZSAzNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKTsKICAgICAgICAgIGNhc2UgMzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpOwogICAgICAgICAgY2FzZSAzODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgY2FzZSAzOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgICAgICAgY2FzZSA0MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgY2FzZSA0MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICAgIGNhc2UgNDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAgICAgICBjYXNlIDQzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgICAgICAgY2FzZSA0NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgICAgY2FzZSA0NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKTsKICAgICAgICAgIGNhc2UgNDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIGNhc2UgNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpOwogICAgICAgICAgY2FzZSA0OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAgICAgICBjYXNlIDUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIGNhc2UgNTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpOwogICAgICAgICAgY2FzZSA1MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgICAgICAgIGNhc2UgNTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgICAgY2FzZSA1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgICAgICAgY2FzZSA1NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKTsKICAgICAgICAgIGNhc2UgNTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICBjYXNlIDU3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpOwogICAgICAgICAgY2FzZSA1ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAgICAgICBjYXNlIDU5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIGNhc2UgNjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpOwogICAgICAgICAgY2FzZSA2MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKTsKICAgICAgICAgIGNhc2UgNjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgICAgY2FzZSA2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCk7CiAgICAgICAgICBjYXNlIDY0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCk7CiAgICAgICAgICBjYXNlIDY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICBjYXNlIDY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAgICAgICBjYXNlIDY3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICBjYXNlIDY4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICBjYXNlIDY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpOwogICAgICAgICAgY2FzZSA3MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAgICAgICBjYXNlIDcxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICBjYXNlIDcyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgICAgICAgY2FzZSA3MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgICBjYXNlIDc1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKTsKICAgICAgICAgIGNhc2UgNzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgY2FzZSA3NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgICBjYXNlIDc4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpOwogICAgICAgICAgY2FzZSA3OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCk7CiAgICAgICAgICBjYXNlIDgwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICAgIGNhc2UgODE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKTsKICAgICAgICAgIGNhc2UgODI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgICAgICAgIGNhc2UgODM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICAgIGNhc2UgODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKTsKICAgICAgICAgIGNhc2UgODU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKTsKICAgICAgICAgIGNhc2UgODY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgICBjYXNlIDg3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKTsKICAgICAgICAgIGNhc2UgODg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKTsKICAgICAgICAgIGNhc2UgODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgICBjYXNlIDkwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpOwogICAgICAgICAgY2FzZSA5MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIGNhc2UgOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgY2FzZSA5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCk7CiAgICAgICAgICBjYXNlIDk0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKTsKICAgICAgICAgIGNhc2UgOTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgICBjYXNlIDk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKTsKICAgICAgICAgIGNhc2UgOTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpOwogICAgICAgICAgY2FzZSA5ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgICAgY2FzZSA5OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgICAgICAgY2FzZSAxMDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAgICAgICBjYXNlIDEwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpOwogICAgICAgICAgY2FzZSAxMDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpOwogICAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICAgIGNhc2UgMTA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgICAgICAgY2FzZSAxMDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpOwogICAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgICAgY2FzZSAxMDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpOwogICAgICAgICAgY2FzZSAxMDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKTsKICAgICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgICBjYXNlIDExMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpOwogICAgICAgICAgY2FzZSAxMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpOwogICAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCk7CiAgICAgICAgICBjYXNlIDExNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKTsKICAgICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgICAgY2FzZSAxMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCk7CiAgICAgICAgICBjYXNlIDExODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKTsKICAgICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgICAgY2FzZSAxMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKTsKICAgICAgICAgIGNhc2UgMTIxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgICAgY2FzZSAxMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgICAgICAgIGNhc2UgMTI0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAgICAgICBjYXNlIDEyNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgICAgY2FzZSAxMjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCk7CiAgICAgICAgICBjYXNlIDEyNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKTsKICAgICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgICAgY2FzZSAxMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKTsKICAgICAgICAgIGNhc2UgMTMwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICBjYXNlIDEzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCk7CiAgICAgICAgICBjYXNlIDEzMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCk7CiAgICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgICBjYXNlIDEzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCk7CiAgICAgICAgICBjYXNlIDEzNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgY2FzZSAxMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAgICAgICBjYXNlIDEzOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCk7CiAgICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgY2FzZSAxNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKTsKICAgICAgICAgIGNhc2UgMTQyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCk7CiAgICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICAgIGNhc2UgMTQ0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpOwogICAgICAgICAgY2FzZSAxNDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgICAgY2FzZSAxNDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAgICAgICBjYXNlIDE0ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKTsKICAgICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIGNhc2UgMTUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgICAgICAgIGNhc2UgMTUxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIGNhc2UgMTUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgICAgICAgIGNhc2UgMTU0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCk7CiAgICAgICAgICBjYXNlIDE1NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICAgIGNhc2UgMTU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgICAgICAgIGNhc2UgMTU3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCk7CiAgICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgY2FzZSAxNTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKTsKICAgICAgICAgIGNhc2UgMTYwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpOwogICAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgICBjYXNlIDE2MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgICAgICAgIGNhc2UgMTYzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCk7CiAgICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIGNhc2UgMTY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpOwogICAgICAgICAgY2FzZSAxNjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgY2FzZSAxNjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgICAgICAgY2FzZSAxNjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgY2FzZSAxNzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKTsKICAgICAgICAgIGNhc2UgMTcyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgY2FzZSAxNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKTsKICAgICAgICAgIGNhc2UgMTc1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgICAgY2FzZSAxNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCk7CiAgICAgICAgICBjYXNlIDE3ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgICAgY2FzZSAxODA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKTsKICAgICAgICAgIGNhc2UgMTgxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpOwogICAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgICBjYXNlIDE4MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCk7CiAgICAgICAgICBjYXNlIDE4NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAgICAgICBjYXNlIDE4NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgICBjYXNlIDE4NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCk7CiAgICAgICAgICBjYXNlIDE4NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCk7CiAgICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgICAgY2FzZSAxODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCk7CiAgICAgICAgICBjYXNlIDE5MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAgICAgICBjYXNlIDE5MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgICAgY2FzZSAxOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKTsKICAgICAgICAgIGNhc2UgMTkzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICAgIGNhc2UgMTk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpOwogICAgICAgICAgY2FzZSAxOTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCk7CiAgICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgICAgY2FzZSAxOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCk7CiAgICAgICAgICBjYXNlIDE5OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKTsKICAgICAgICAgIGNhc2UgMjAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKTsKICAgICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgYml0RmllbGQyXyA9IDA7CiAgICAgICAgYml0RmllbGQzXyA9IDA7CiAgICAgICAgYml0RmllbGQ0XyA9IDA7CiAgICAgICAgYml0RmllbGQ1XyA9IDA7CiAgICAgICAgYml0RmllbGQ2XyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMShyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMl8gIT0gMCkgeyBidWlsZFBhcnRpYWwyKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQzXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDMocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDRfICE9IDApIHsgYnVpbGRQYXJ0aWFsNChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkNV8gIT0gMCkgeyBidWlsZFBhcnRpYWw1KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQ2XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDYocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEJvb2wxXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCb29sMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEJ5dGVzMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEJ5dGVzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbERvdWJsZTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRG91YmxlM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEVudW00XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xFbnVtNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGaXhlZDMyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGaXhlZDY0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEZsb2F0N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEZsb2F0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEludDMyOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEludDMyOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEludDY0OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEludDY0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbE1lc3NhZ2UxMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmJ1aWxkKEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTaW50MzIxM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTaW50NjQxNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTdHJpbmcxNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xVaW50MzIxNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFVpbnQ2NDE3XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xVaW50NjQxN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkJvb2wxOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJEb3VibGUyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkVudW0yMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkludDMyMjVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMySW50MzIyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkludDY0MjZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMySW50NjQyNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmJ1aWxkKEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTaW50MzIzMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTaW50NjQzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTdHJpbmczMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxXyA9IGJpdEZpZWxkMV87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyVWludDMyMzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyVWludDY0MzRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRCb29sMzVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRCb29sMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjREb3VibGUzN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRFbnVtMzhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRFbnVtMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5idWlsZChGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0VWludDMyNTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0VWludDY0NTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyQm9vbDUyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCb29sNTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyQnl0ZXM1M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkJ5dGVzNTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRG91YmxlNTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRG91YmxlNTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRW51bTU1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJFbnVtNTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRml4ZWQzMjU2XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDMyNTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRml4ZWQ2NDU3XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDY0NTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRmxvYXQ1OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZsb2F0NThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50MzI1OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkludDMyNTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50NjQ2MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkludDY0NjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyTWVzc2FnZTYxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmJ1aWxkKEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ludDMyNjRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ludDMyNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMl8gPSBiaXRGaWVsZDJfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNpbnQ2NDY1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlN0cmluZzY2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQzMjY3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQ2NDY4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJvb2w2OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Qm9vbDY5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRCeXRlczcwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NERvdWJsZTcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEVudW03Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RW51bTcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQzMjczXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQ2NDc0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRGbG9hdDc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDMyNzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRJbnQzMjc2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDY0NzdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRJbnQ2NDc3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5idWlsZChGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQzMjgxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFN0cmluZzgzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQzMjg0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQ2NDg1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRW51bTg5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5idWlsZChGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDNfID0gYml0RmllbGQzXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RW51bTEwNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5idWlsZChGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyQm9vbDEyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJCeXRlczEyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRW51bTEyM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRW51bTEyM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJGbG9hdDEyNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMySW50MzIxMjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJJbnQzMjEyN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMySW50NjQxMjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQ0XyA9IGJpdEZpZWxkNF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5idWlsZChGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTaW50MzIxMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTaW50NjQxMzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJVaW50MzIxMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJVaW50NjQxMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEJvb2wxMzdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEJvb2wxMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjREb3VibGUxMzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEVudW0xNDBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEVudW0xNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RmxvYXQxNDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50MzIxNDRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50NjQxNDVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5idWlsZChGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTaW50MzIxNDlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTaW50NjQxNTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRVaW50MzIxNTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRVaW50NjQxNTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0Jvb2wxNTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0Jvb2wxNTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0VudW0xNTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0VudW0xNTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWw1KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNV8gPSBiaXRGaWVsZDVfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDMyMTYxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDY0MTYyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuYnVpbGQoRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCb29sMTcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkJ5dGVzMTcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyRG91YmxlMTczXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJFbnVtMTc0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZsb2F0MTc3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDMyMTc4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDY0MTc5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuYnVpbGQoRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50MzIxODNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ludDMyMTgzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50NjQxODRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ludDY0MTg0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU3RyaW5nMTg1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50MzIxODZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyVWludDMyMTg2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50NjQxODdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyVWludDY0MTg3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCb29sMTg4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjREb3VibGUxOTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0RG91YmxlMTkwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRFbnVtMTkxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsNihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDZfID0gYml0RmllbGQ2XzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0RmxvYXQxOTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGbG9hdDE5NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0SW50MzIxOTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRJbnQzMjE5NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0SW50NjQxOTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmJ1aWxkKEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U3RyaW5nMjAyXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0VWludDMyMjAzXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwODsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKS52YWx1ZXMoKSkgewogICAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGl0ZW0gOiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgaXRlbSA6IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBpdGVtIDogZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCb29sMV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xCb29sMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sQnl0ZXMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sQnl0ZXMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRG91YmxlM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xEb3VibGUzX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbERvdWJsZTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF9fID0gRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBCb29sRW51bTRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDQsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEVudW00X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEVudW00X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQzMjVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkMzI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDY0Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGbG9hdDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N19fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xGbG9hdDdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sSW50MzI4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQzMjhfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sSW50MzI4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEludDY0OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEludDY0OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sTWVzc2FnZTEwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sTWVzc2FnZTEwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTZml4ZWQzMjExX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQzMjEzX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFNpbnQzMjEzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ludDY0MTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTaW50NjQxNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICAgIGNhc2UgMTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU3RyaW5nMTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTdHJpbmcxNV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTdHJpbmcxNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMgogICAgICAgICAgICAgIGNhc2UgMTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sVWludDMyMTZfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sVWludDMyMTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgICBjYXNlIDEzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50NjQxN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDY0MTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM4CiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJCeXRlczE5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYyCiAgICAgICAgICAgICAgY2FzZSAxNzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXyA9IEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIxLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRW51bTIxX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTcwCiAgICAgICAgICAgICAgY2FzZSAxNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50MzIyNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDIKICAgICAgICAgICAgICBjYXNlIDIxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGNhc2UgMjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIyNgogICAgICAgICAgICAgIGNhc2UgMjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjM0CiAgICAgICAgICAgICAgY2FzZSAyNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MgogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBjYXNlIDI2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY2CiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3NAogICAgICAgICAgICAgIGNhc2UgMjgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MgogICAgICAgICAgICAgIGNhc2UgMjkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4X18gPSBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBGaXhlZDY0RW51bTM4X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgzOCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNgogICAgICAgICAgICAgIGNhc2UgMzE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNAogICAgICAgICAgICAgIGNhc2UgMzIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMgogICAgICAgICAgICAgIGNhc2UgMzMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGbG9hdDQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMAogICAgICAgICAgICAgIGNhc2UgMzM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDMyNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM4CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50NjQ0M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNDYKICAgICAgICAgICAgICBjYXNlIDM1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzU0CiAgICAgICAgICAgICAgY2FzZSAzNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjIKICAgICAgICAgICAgICBjYXNlIDM3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3MAogICAgICAgICAgICAgIGNhc2UgMzc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzgKICAgICAgICAgICAgICBjYXNlIDM4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzg2CiAgICAgICAgICAgICAgY2FzZSAzOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzk0CiAgICAgICAgICAgICAgY2FzZSA0MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwMgogICAgICAgICAgICAgIGNhc2UgNDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTAKICAgICAgICAgICAgICBjYXNlIDQxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyQm9vbDUyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCb29sNTJfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkJvb2w1Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxOAogICAgICAgICAgICAgIGNhc2UgNDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyQnl0ZXM1M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJ5dGVzNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJCeXRlczUzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDI2CiAgICAgICAgICAgICAgY2FzZSA0MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRG91YmxlNTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJEb3VibGU1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRG91YmxlNTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MzQKICAgICAgICAgICAgICBjYXNlIDQ0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfXyA9IEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBJbnQzMkVudW01NV9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoNTUsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkVudW01NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRW51bTU1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NDIKICAgICAgICAgICAgICBjYXNlIDQ1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQzMjU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1MAogICAgICAgICAgICAgIGNhc2UgNDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRml4ZWQ2NDU3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDU4CiAgICAgICAgICAgICAgY2FzZSA0NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGbG9hdDU4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkZsb2F0NThfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkZsb2F0NThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NjYKICAgICAgICAgICAgICBjYXNlIDQ3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQzMjU5X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJJbnQzMjU5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDc0CiAgICAgICAgICAgICAgY2FzZSA0ODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkludDY0NjBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF9fLmdldEtleSgpLCBmaWVsZE1hcEludDMySW50NjQ2MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4MgogICAgICAgICAgICAgIGNhc2UgNDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyTWVzc2FnZTYxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyTWVzc2FnZTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ5MAogICAgICAgICAgICAgIGNhc2UgNDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OTgKICAgICAgICAgICAgICBjYXNlIDUwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTA2CiAgICAgICAgICAgICAgY2FzZSA1MTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDMyNjRfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTE0CiAgICAgICAgICAgICAgY2FzZSA1MjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQ2NDY1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDY0NjVfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlNpbnQ2NDY1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTIyCiAgICAgICAgICAgICAgY2FzZSA1MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU3RyaW5nNjZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTdHJpbmc2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyU3RyaW5nNjZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MzAKICAgICAgICAgICAgICBjYXNlIDUzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N19fLmdldEtleSgpLCBmaWVsZE1hcEludDMyVWludDMyNjdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MzgKICAgICAgICAgICAgICBjYXNlIDU0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50NjQ2OF9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyVWludDY0NjhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NDYKICAgICAgICAgICAgICBjYXNlIDU1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEJvb2w2OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU1NAogICAgICAgICAgICAgIGNhc2UgNTYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Qnl0ZXM3MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRCeXRlczcwX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRCeXRlczcwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTYyCiAgICAgICAgICAgICAgY2FzZSA1NzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjREb3VibGU3MV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0RG91YmxlNzFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NzAKICAgICAgICAgICAgICBjYXNlIDU3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRFbnVtNzJfXyA9IEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBJbnQ2NEVudW03Ml9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoNzIsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEVudW03Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0RW51bTcyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NzgKICAgICAgICAgICAgICBjYXNlIDU4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQzMjczX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4NgogICAgICAgICAgICAgIGNhc2UgNTk0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTk0CiAgICAgICAgICAgICAgY2FzZSA2MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEZsb2F0NzVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MDIKICAgICAgICAgICAgICBjYXNlIDYxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRJbnQzMjc2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjEwCiAgICAgICAgICAgICAgY2FzZSA2MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N19fLmdldEtleSgpLCBmaWVsZE1hcEludDY0SW50NjQ3N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYxOAogICAgICAgICAgICAgIGNhc2UgNjI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0TWVzc2FnZTc4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYyNgogICAgICAgICAgICAgIGNhc2UgNjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MzQKICAgICAgICAgICAgICBjYXNlIDY0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQyCiAgICAgICAgICAgICAgY2FzZSA2NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUwCiAgICAgICAgICAgICAgY2FzZSA2NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjU4CiAgICAgICAgICAgICAgY2FzZSA2NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fLmdldEtleSgpLCBmaWVsZE1hcEludDY0U3RyaW5nODNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NjYKICAgICAgICAgICAgICBjYXNlIDY3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0VWludDMyODRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NzQKICAgICAgICAgICAgICBjYXNlIDY4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0VWludDY0ODVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0VWludDY0ODVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODIKICAgICAgICAgICAgICBjYXNlIDY5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY5MAogICAgICAgICAgICAgIGNhc2UgNjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjk4CiAgICAgICAgICAgICAgY2FzZSA3MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MDYKICAgICAgICAgICAgICBjYXNlIDcxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXyA9IEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBTZml4ZWQzMkVudW04OV9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoODksIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRW51bTg5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MTQKICAgICAgICAgICAgICBjYXNlIDcyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyMgogICAgICAgICAgICAgIGNhc2UgNzMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzMwCiAgICAgICAgICAgICAgY2FzZSA3Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MzgKICAgICAgICAgICAgICBjYXNlIDc0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQ2CiAgICAgICAgICAgICAgY2FzZSA3NTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1NAogICAgICAgICAgICAgIGNhc2UgNzYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc2MgogICAgICAgICAgICAgIGNhc2UgNzcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzAKICAgICAgICAgICAgICBjYXNlIDc3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzc4CiAgICAgICAgICAgICAgY2FzZSA3ODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzg2CiAgICAgICAgICAgICAgY2FzZSA3OTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzk0CiAgICAgICAgICAgICAgY2FzZSA4MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMgogICAgICAgICAgICAgIGNhc2UgODEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEwCiAgICAgICAgICAgICAgY2FzZSA4MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTgKICAgICAgICAgICAgICBjYXNlIDgyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODI2CiAgICAgICAgICAgICAgY2FzZSA4MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgzNAogICAgICAgICAgICAgIGNhc2UgODQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NDIKICAgICAgICAgICAgICBjYXNlIDg1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18gPSBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMTA2LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODUwCiAgICAgICAgICAgICAgY2FzZSA4NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg1OAogICAgICAgICAgICAgIGNhc2UgODY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NjYKICAgICAgICAgICAgICBjYXNlIDg3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODc0CiAgICAgICAgICAgICAgY2FzZSA4ODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODgyCiAgICAgICAgICAgICAgY2FzZSA4OTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDY0MTExX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEludDY0MTExX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODkwCiAgICAgICAgICAgICAgY2FzZSA4OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTgKICAgICAgICAgICAgICBjYXNlIDkwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MDYKICAgICAgICAgICAgICBjYXNlIDkxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MTQKICAgICAgICAgICAgICBjYXNlIDkyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkyMgogICAgICAgICAgICAgIGNhc2UgOTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTMwCiAgICAgICAgICAgICAgY2FzZSA5Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzOAogICAgICAgICAgICAgIGNhc2UgOTQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTQ2CiAgICAgICAgICAgICAgY2FzZSA5NTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NTQKICAgICAgICAgICAgICBjYXNlIDk2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NjIKICAgICAgICAgICAgICBjYXNlIDk3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NzAKICAgICAgICAgICAgICBjYXNlIDk3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NzgKICAgICAgICAgICAgICBjYXNlIDk4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM19fID0gRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkTWFwU2ludDMyRW51bTEyM19fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMTIzLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJFbnVtMTIzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRW51bTEyM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTg2CiAgICAgICAgICAgICAgY2FzZSA5OTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTk0CiAgICAgICAgICAgICAgY2FzZSAxMDAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwMDIKICAgICAgICAgICAgICBjYXNlIDEwMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAxMAogICAgICAgICAgICAgIGNhc2UgMTAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDMyMTI3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJJbnQzMjEyN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwMTgKICAgICAgICAgICAgICBjYXNlIDEwMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDI2CiAgICAgICAgICAgICAgY2FzZSAxMDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDM0CiAgICAgICAgICAgICAgY2FzZSAxMDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0MgogICAgICAgICAgICAgIGNhc2UgMTA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNTAKICAgICAgICAgICAgICBjYXNlIDEwNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNTgKICAgICAgICAgICAgICBjYXNlIDEwNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNjYKICAgICAgICAgICAgICBjYXNlIDEwNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA3NAogICAgICAgICAgICAgIGNhc2UgMTA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA4MgogICAgICAgICAgICAgIGNhc2UgMTA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA5MAogICAgICAgICAgICAgIGNhc2UgMTA5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDk4CiAgICAgICAgICAgICAgY2FzZSAxMTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRCeXRlczEzOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMDYKICAgICAgICAgICAgICBjYXNlIDExMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTExNAogICAgICAgICAgICAgIGNhc2UgMTEyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RW51bTE0MF9fID0gRmllbGRNYXBTaW50NjRFbnVtMTQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkTWFwU2ludDY0RW51bTE0MF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMTQwLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRFbnVtMTQwX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0RW51bTE0MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEyMgogICAgICAgICAgICAgIGNhc2UgMTEzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTMwCiAgICAgICAgICAgICAgY2FzZSAxMTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMzgKICAgICAgICAgICAgICBjYXNlIDExNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0NgogICAgICAgICAgICAgIGNhc2UgMTE1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRJbnQzMjE0NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNTQKICAgICAgICAgICAgICBjYXNlIDExNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRJbnQ2NDE0NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTYyCiAgICAgICAgICAgICAgY2FzZSAxMTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTcwCiAgICAgICAgICAgICAgY2FzZSAxMTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE3OAogICAgICAgICAgICAgIGNhc2UgMTE4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExODYKICAgICAgICAgICAgICBjYXNlIDExOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50MzIxNDlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExOTQKICAgICAgICAgICAgICBjYXNlIDEyMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMDIKICAgICAgICAgICAgICBjYXNlIDEyMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxMAogICAgICAgICAgICAgIGNhc2UgMTIxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxOAogICAgICAgICAgICAgIGNhc2UgMTIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyNgogICAgICAgICAgICAgIGNhc2UgMTIzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMzQKICAgICAgICAgICAgICBjYXNlIDEyNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjQyCiAgICAgICAgICAgICAgY2FzZSAxMjUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI1MAogICAgICAgICAgICAgIGNhc2UgMTI1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18gPSBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRNYXBTdHJpbmdFbnVtMTU3X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxNTcsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjU4CiAgICAgICAgICAgICAgY2FzZSAxMjY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI2NgogICAgICAgICAgICAgIGNhc2UgMTI3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyNzQKICAgICAgICAgICAgICBjYXNlIDEyODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjgyCiAgICAgICAgICAgICAgY2FzZSAxMjkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjkwCiAgICAgICAgICAgICAgY2FzZSAxMjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjk4CiAgICAgICAgICAgICAgY2FzZSAxMzA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMDYKICAgICAgICAgICAgICBjYXNlIDEzMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMTQKICAgICAgICAgICAgICBjYXNlIDEzMjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMjIKICAgICAgICAgICAgICBjYXNlIDEzMzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMzMAogICAgICAgICAgICAgIGNhc2UgMTMzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzM4CiAgICAgICAgICAgICAgY2FzZSAxMzQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM0NgogICAgICAgICAgICAgIGNhc2UgMTM1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzU0CiAgICAgICAgICAgICAgY2FzZSAxMzYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDY0MTcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNjIKICAgICAgICAgICAgICBjYXNlIDEzNzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJCb29sMTcxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM3MAogICAgICAgICAgICAgIGNhc2UgMTM3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCeXRlczE3MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzc4CiAgICAgICAgICAgICAgY2FzZSAxMzg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRG91YmxlMTczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzODYKICAgICAgICAgICAgICBjYXNlIDEzOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkVudW0xNzRfXyA9IEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcFVpbnQzMkVudW0xNzRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDE3NCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkVudW0xNzRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzOTQKICAgICAgICAgICAgICBjYXNlIDE0MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQwMgogICAgICAgICAgICAgIGNhc2UgMTQxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDEwCiAgICAgICAgICAgICAgY2FzZSAxNDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MTgKICAgICAgICAgICAgICBjYXNlIDE0MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMySW50MzIxNzhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDI2CiAgICAgICAgICAgICAgY2FzZSAxNDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMySW50NjQxNzlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkludDY0MTc5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQzNAogICAgICAgICAgICAgIGNhc2UgMTQ0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ0MgogICAgICAgICAgICAgIGNhc2UgMTQ1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NTAKICAgICAgICAgICAgICBjYXNlIDE0NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDU4CiAgICAgICAgICAgICAgY2FzZSAxNDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDY2CiAgICAgICAgICAgICAgY2FzZSAxNDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDc0CiAgICAgICAgICAgICAgY2FzZSAxNDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0ODIKICAgICAgICAgICAgICBjYXNlIDE0OTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0OTAKICAgICAgICAgICAgICBjYXNlIDE0OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0OTgKICAgICAgICAgICAgICBjYXNlIDE1MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRCb29sMTg4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUwNgogICAgICAgICAgICAgIGNhc2UgMTUxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTE0CiAgICAgICAgICAgICAgY2FzZSAxNTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MjIKICAgICAgICAgICAgICBjYXNlIDE1MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXyA9IEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDE5MSwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MzAKICAgICAgICAgICAgICBjYXNlIDE1Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUzOAogICAgICAgICAgICAgIGNhc2UgMTU0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRGbG9hdDE5NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NTQKICAgICAgICAgICAgICBjYXNlIDE1NjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDMyMTk1X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTYyCiAgICAgICAgICAgICAgY2FzZSAxNTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEludDY0MTk2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU3MAogICAgICAgICAgICAgIGNhc2UgMTU3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU3OAogICAgICAgICAgICAgIGNhc2UgMTU4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1ODYKICAgICAgICAgICAgICBjYXNlIDE1OTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTk0CiAgICAgICAgICAgICAgY2FzZSAxNjAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAyCiAgICAgICAgICAgICAgY2FzZSAxNjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjEwCiAgICAgICAgICAgICAgY2FzZSAxNjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MTgKICAgICAgICAgICAgICBjYXNlIDE2MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MjYKICAgICAgICAgICAgICBjYXNlIDE2MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDJfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDNfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDRfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDVfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDZfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xCb29sMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQm9vbDFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xCb29sMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxXyA9IGZpZWxkTWFwQm9vbEJvb2wxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQm9vbDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwQm9vbEJvb2wxT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xCeXRlczJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfID0gZmllbGRNYXBCb29sQnl0ZXMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEJ5dGVzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEJvb2xEb3VibGUzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xEb3VibGUzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbERvdWJsZTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRG91YmxlM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfID0gZmllbGRNYXBCb29sRG91YmxlM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRG91YmxlM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sRW51bTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRW51bTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEVudW00XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRW51bTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF8gPSBmaWVsZE1hcEJvb2xFbnVtNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBCb29sRW51bTRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEJvb2xFbnVtNE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xFbnVtNCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEJvb2xFbnVtNE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEZpeGVkMzI1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkMzI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDMyNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQzMjVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDMyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEZpeGVkMzI1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQzMjVfID0gZmllbGRNYXBCb29sRml4ZWQzMjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRml4ZWQzMjUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xGaXhlZDMyNSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sRml4ZWQ2NDZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRml4ZWQ2NDZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRml4ZWQ2NDZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPSBmaWVsZE1hcEJvb2xGaXhlZDY0Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEZpeGVkNjQ2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwQm9vbEZsb2F0N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZsb2F0N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZsb2F0N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZsb2F0N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRmxvYXQ3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3XyA9IGZpZWxkTWFwQm9vbEZsb2F0N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZsb2F0N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xJbnQzMjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEludDMyOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sSW50MzI4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sSW50MzI4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sSW50MzI4XyA9IGZpZWxkTWFwQm9vbEludDMyOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDMyOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbEludDY0OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sSW50NjQ5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDY0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50NjQ5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQ2NDlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEludDY0OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDY0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEludDY0OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEludDY0OV8gPSBmaWVsZE1hcEJvb2xJbnQ2NDlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50NjQ5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIgZmllbGRNYXBCb29sTWVzc2FnZTEwQ29udmVydGVyID0gbmV3IEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sTWVzc2FnZTEwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwQm9vbE1lc3NhZ2UxMEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTZml4ZWQzMjExXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkNjQxMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ludDMyMTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDMyMTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU2ludDMyMTNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM18gPSBmaWVsZE1hcEJvb2xTaW50MzIxM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNpbnQzMjEzKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTaW50NjQxNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50NjQxNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDY0MTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTaW50NjQxNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGZpZWxkTWFwQm9vbFNpbnQ2NDE0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTdHJpbmcxNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGZpZWxkTWFwQm9vbFN0cmluZzE1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU3RyaW5nMTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50MzIxNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sVWludDMyMTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xVaW50MzIxNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGZpZWxkTWFwQm9vbFVpbnQzMjE2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xVaW50MzIxNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFVpbnQ2NDE3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbFVpbnQ2NDE3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfID0gZmllbGRNYXBCb29sVWludDY0MTdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQm9vbDE4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCb29sMThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkJvb2wxOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBmaWVsZE1hcEZpeGVkMzJCb29sMThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJCb29sMThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJCb29sMTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJFbnVtMjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gZmllbGRNYXBGaXhlZDMyRW51bTIxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRW51bTIxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXyA9IGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID0gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJGbG9hdDI0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8gPSBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50MzIyNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQzMjI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50MzIyNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50MzIyNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJJbnQzMjI1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50MzIyNV8gPSBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50MzIyNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMySW50MzIyNSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMySW50NjQyNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkludDY0MjZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50NjQyNl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkludDY0MjZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMySW50NjQyNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfID0gZmllbGRNYXBGaXhlZDMySW50NjQyNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlciBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0J1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9IGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPSBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID0gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID0gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9IGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyVWludDMyMzNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyVWludDMyMzNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPSBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyVWludDY0MzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDY0MzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyVWludDY0MzRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPSBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qm9vbDM1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qm9vbDM1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRCb29sMzVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBmaWVsZE1hcEZpeGVkNjRCb29sMzVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPSBmaWVsZE1hcEZpeGVkNjREb3VibGUzN18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjREb3VibGUzNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RW51bTM4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRFbnVtMzhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID0gZmllbGRNYXBGaXhlZDY0RW51bTM4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDMyNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlciBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XyA9IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XyA9IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDMyNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9IGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID0gZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfID0gZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50MzI1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID0gZmllbGRNYXBGaXhlZDY0VWludDMyNTBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDY0NTFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0VWludDY0NTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8gPSBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJCb29sNTJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJvb2w1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJCb29sNTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJCb29sNTJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkJvb2w1Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJCb29sNTJfID0gZmllbGRNYXBJbnQzMkJvb2w1Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCb29sNTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkJvb2w1MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJvb2w1MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBJbnQzMkJ5dGVzNTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJCeXRlczUzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCeXRlczUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJ5dGVzNTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJ5dGVzNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyQnl0ZXM1M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzXyA9IGZpZWxkTWFwSW50MzJCeXRlczUzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkJ5dGVzNTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyQnl0ZXM1MygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyQnl0ZXM1MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwSW50MzJEb3VibGU1NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRG91YmxlNTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkRvdWJsZTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRG91YmxlNTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkRvdWJsZTU0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRG91YmxlNTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyRG91YmxlNTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRG91YmxlNTRfID0gZmllbGRNYXBJbnQzMkRvdWJsZTU0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50MzJEb3VibGU1NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJEb3VibGU1NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJEb3VibGU1NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJFbnVtNTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRW51bTU1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRW51bTU1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRW51bTU1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJFbnVtNTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRW51bTU1XyA9IGZpZWxkTWFwSW50MzJFbnVtNTVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRW51bTU1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDMyRW51bTU1TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkVudW01NSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJFbnVtNTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJGaXhlZDMyNTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9IGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyRml4ZWQ2NDU3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPSBmaWVsZE1hcEludDMyRml4ZWQ2NDU3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZsb2F0NThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGbG9hdDU4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRmxvYXQ1OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZsb2F0NThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJGbG9hdDU4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZsb2F0NThfID0gZmllbGRNYXBJbnQzMkZsb2F0NThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkludDMyNTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkludDMyNTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkludDMyNTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV8gPSBmaWVsZE1hcEludDMySW50MzI1OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkludDY0NjBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkludDY0NjBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF8gPSBmaWVsZE1hcEludDMySW50NjQ2MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfID0gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID0gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50MzI2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDMyNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyU2ludDMyNjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDMyNjRfID0gZmllbGRNYXBJbnQzMlNpbnQzMjY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQzMjY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJTaW50NjQ2NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ludDY0NjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTaW50NjQ2NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPSBmaWVsZE1hcEludDMyU2ludDY0NjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU3RyaW5nNjZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTdHJpbmc2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTdHJpbmc2Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPSBmaWVsZE1hcEludDMyU3RyaW5nNjZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlVpbnQzMjY3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDMyNjdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJVaW50MzI2N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N18gPSBmaWVsZE1hcEludDMyVWludDMyNjdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDY0NjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlVpbnQ2NDY4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGZpZWxkTWFwSW50MzJVaW50NjQ2OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50NjQ2OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyVWludDY0NjhPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRCb29sNjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRCb29sNjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEJvb2w2OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfID0gZmllbGRNYXBJbnQ2NEJvb2w2OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Qnl0ZXM3MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRCeXRlczcwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEludDY0RG91YmxlNzFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjREb3VibGU3MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NERvdWJsZTcxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGZpZWxkTWFwSW50NjREb3VibGU3MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RW51bTcyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RW51bTcyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEVudW03MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRFbnVtNzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyXyA9IGZpZWxkTWFwSW50NjRFbnVtNzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RW51bTcyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID0gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID0gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZsb2F0NzVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RmxvYXQ3NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRGbG9hdDc1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gZmllbGRNYXBJbnQ2NEZsb2F0NzVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0SW50MzI3Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDMyNzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0SW50MzI3Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9IGZpZWxkTWFwSW50NjRJbnQzMjc2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQ2NDc3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50NjQ3N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0SW50NjQ3N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRJbnQ2NDc3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfID0gZmllbGRNYXBJbnQ2NEludDY0NzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50NjQ3N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50NjQ3N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRNZXNzYWdlNzhCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPSBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDMyODFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50MzI4MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFNpbnQzMjgxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGZpZWxkTWFwSW50NjRTaW50MzI4MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDY0ODJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTaW50NjQ4Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPSBmaWVsZE1hcEludDY0U2ludDY0ODJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFN0cmluZzgzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFN0cmluZzgzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGZpZWxkTWFwSW50NjRTdHJpbmc4M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50MzI4NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0VWludDMyODRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfID0gZmllbGRNYXBJbnQ2NFVpbnQzMjg0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFVpbnQzMjg0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0VWludDY0ODVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50NjQ4NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFVpbnQ2NDg1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGZpZWxkTWFwSW50NjRVaW50NjQ4NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDY0ODVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPSBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRW51bTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkVudW04OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID0gZmllbGRNYXBTZml4ZWQzMkVudW04OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50MzI5M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50MzI5M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPSBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPSBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPSBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9IGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID0gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8gPSBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID0gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9IGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID0gZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID0gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPSBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID0gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPSBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XyA9IGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPSBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPiBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJCb29sMTIwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyQm9vbDEyMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJvb2wxMjAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRW51bTEyM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJFbnVtMTIzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkVudW0xMjNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfID0gZmllbGRNYXBTaW50MzJFbnVtMTIzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9IGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID0gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkZsb2F0MTI2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPSBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkludDMyMTI3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPSBmaWVsZE1hcFNpbnQzMkludDMyMTI3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQzMjEyN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJJbnQzMjEyNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMySW50NjQxMjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMySW50NjQxMjhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfID0gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMySW50NjQxMjhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlciBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9IGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPSBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ludDMyMTMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfID0gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTaW50MzIxMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ludDY0MTMzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfID0gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJVaW50MzIxMzVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJVaW50MzIxMzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPSBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJVaW50NjQxMzZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJVaW50NjQxMzZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPSBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDY0Qm9vbDEzN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRCb29sMTM3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCb29sMTM3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0Qm9vbDEzN18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRCeXRlczEzOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gZmllbGRNYXBTaW50NjRCeXRlczEzOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjREb3VibGUxMzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPSBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RW51bTE0MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRFbnVtMTQwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEVudW0xNDBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID0gZmllbGRNYXBTaW50NjRFbnVtMTQwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID0gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9IGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M18gPSBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRGbG9hdDE0MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50MzIxNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0SW50MzIxNDRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9IGZpZWxkTWFwU2ludDY0SW50MzIxNDRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0SW50NjQxNDVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9IGZpZWxkTWFwU2ludDY0SW50NjQxNDVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlciBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XyA9IGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XyA9IGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50MzIxNDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9IGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0U2ludDY0MTUwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID0gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID0gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0VWludDMyMTUyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID0gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0VWludDY0MTUzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRVaW50NjQxNTNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18gPSBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0VWludDY0MTUzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdCb29sMTU0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdCb29sMTU0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0XyA9IGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTdHJpbmdCeXRlczE1NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdCeXRlczE1NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdCeXRlczE1NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID0gZmllbGRNYXBTdHJpbmdCeXRlczE1NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID0gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRW51bTE1N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0VudW0xNTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRW51bTE1N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nRW51bTE1N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRW51bTE1N18gPSBmaWVsZE1hcFN0cmluZ0VudW0xNTdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID0gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9IGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nSW50MzIxNjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50NjQxNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ludDY0MTYyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlciBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID0gZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9IGZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9IGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQm9vbDE3MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJCb29sMTcxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGZpZWxkTWFwVWludDMyQm9vbDE3MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJCeXRlczE3Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID0gZmllbGRNYXBVaW50MzJCeXRlczE3Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRG91YmxlMTczXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRG91YmxlMTczKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyRW51bTE3NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkVudW0xNzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRW51bTE3NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF8gPSBmaWVsZE1hcFVpbnQzMkVudW0xNzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID0gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPSBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGbG9hdDE3N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRmxvYXQxNzdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9IGZpZWxkTWFwVWludDMyRmxvYXQxNzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMySW50MzIxNzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMySW50MzIxNzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMySW50MzIxNzhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9IGZpZWxkTWFwVWludDMySW50MzIxNzhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkludDY0MTc5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBmaWVsZE1hcFVpbnQzMkludDY0MTc5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMySW50NjQxNzlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPiBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID0gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9IGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTaW50MzIxODNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50MzIxODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDMyMTgzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTaW50MzIxODNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPSBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTaW50NjQxODRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDY0MTg0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTaW50NjQxODRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPSBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU3RyaW5nMTg1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTdHJpbmcxODUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJVaW50MzIxODZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50MzIxODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9IGZpZWxkTWFwVWludDMyVWludDMyMTg2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJVaW50NjQxODdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9IGZpZWxkTWFwVWludDMyVWludDY0MTg3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50NjRCb29sMTg4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJvb2wxODhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRCb29sMTg4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGZpZWxkTWFwVWludDY0Qm9vbDE4OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qm9vbDE4OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRCb29sMTg4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwVWludDY0RG91YmxlMTkwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjREb3VibGUxOTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjREb3VibGUxOTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9IGZpZWxkTWFwVWludDY0RG91YmxlMTkwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0RW51bTE5MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV8gPSBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPSBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID0gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGbG9hdDE5NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0RmxvYXQxOTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50MzIxOTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50MzIxOTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRJbnQzMjE5NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfID0gZmllbGRNYXBVaW50NjRJbnQzMjE5NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50MzIxOTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50NjQxOTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQ2NDE5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50NjQxOTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfID0gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50NjQxOTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID0gZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID0gZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ludDMyMjAwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID0gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0U2ludDMyMjAwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50NjQyMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ludDY0MjAxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDY0MjAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRTaW50NjQyMDFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPSBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ludDY0MjAxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPSBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50MzIyMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDMyMjAzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRVaW50MzIyMDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPSBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0VWludDMyMjAzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9IGZpZWxkTWFwVWludDY0VWludDY0MjA0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFXzFfRklFTERfTlVNQkVSID0gMTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkRvdWJsZT4gZmllbGREb3VibGUxID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUXzJfRklFTERfTlVNQkVSID0gMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkZsb2F0PiBmaWVsZEZsb2F0MiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkZsb2F0LmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0XzNfRklFTERfTlVNQkVSID0gMzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGZpZWxkSW50NjQzID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UNjRfNF9GSUVMRF9OVU1CRVIgPSA0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuTG9uZz4gZmllbGRVaW50NjQ0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81X0ZJRUxEX05VTUJFUiA9IDU7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEludDMyNSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF82X0ZJRUxEX05VTUJFUiA9IDY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBmaWVsZEZpeGVkNjQ2ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyXzdfRklFTERfTlVNQkVSID0gNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkRml4ZWQzMjcgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfOF9GSUVMRF9OVU1CRVIgPSA4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRCb29sOCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU1RSSU5HXzlfRklFTERfTlVNQkVSID0gOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLlN0cmluZz4gZmllbGRTdHJpbmc5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01FU1NBR0VfMTBfRklFTERfTlVNQkVSID0gMTA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4gZmllbGRNZXNzYWdlMTAgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5jbGFzcywKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JZVEVTXzExX0ZJRUxEX05VTUJFUiA9IDExOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkQnl0ZXMxMSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl8xMl9GSUVMRF9OVU1CRVIgPSAxMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkVWludDMyMTIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fMTNfRklFTERfTlVNQkVSID0gMTM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZmllbGRFbnVtMTMgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bS5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl8xNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkU2ZpeGVkMzIxNCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfMTVfRklFTERfTlVNQkVSID0gMTU7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBmaWVsZFNmaXhlZDY0MTUgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkU2ludDMyMTYgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF8xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGZpZWxkU2ludDY0MTcgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPj4gZmllbGREb3VibGVMaXN0MTggPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfTElTVF8xOV9GSUVMRF9OVU1CRVIgPSAxOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0Pj4gZmllbGRGbG9hdExpc3QxOSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkZsb2F0LmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0X0xJU1RfMjBfRklFTERfTlVNQkVSID0gMjA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRJbnQ2NExpc3QyMCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfMjFfRklFTERfTlVNQkVSID0gMjE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRVaW50NjRMaXN0MjEgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyX0xJU1RfMjJfRklFTERfTlVNQkVSID0gMjI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRJbnQzMkxpc3QyMiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF9MSVNUXzIzX0ZJRUxEX05VTUJFUiA9IDIzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IGZpZWxkRml4ZWQ2NExpc3QyMyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl9MSVNUXzI0X0ZJRUxEX05VTUJFUiA9IDI0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkRml4ZWQzMkxpc3QyNCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF9MSVNUXzI1X0ZJRUxEX05VTUJFUiA9IDI1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4+IGZpZWxkQm9vbExpc3QyNSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU1RSSU5HX0xJU1RfMjZfRklFTERfTlVNQkVSID0gMjY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+PiBmaWVsZFN0cmluZ0xpc3QyNiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFX0xJU1RfMjdfRklFTERfTlVNQkVSID0gMjc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZT4+IGZpZWxkTWVzc2FnZUxpc3QyNyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLmNsYXNzLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQllURVNfTElTVF8yOF9GSUVMRF9OVU1CRVIgPSAyODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPj4gZmllbGRCeXRlc0xpc3QyOCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9MSVNUXzI5X0ZJRUxEX05VTUJFUiA9IDI5OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkVWludDMyTGlzdDI5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9FTlVNX0xJU1RfMzBfRklFTERfTlVNQkVSID0gMzA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4+IGZpZWxkRW51bUxpc3QzMCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyX0xJU1RfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRTZml4ZWQzMkxpc3QzMSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfTElTVF8zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiBmaWVsZFNmaXhlZDY0TGlzdDMyID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UMzJfTElTVF8zM19GSUVMRF9OVU1CRVIgPSAzMzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBmaWVsZFNpbnQzMkxpc3QzMyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0X0xJU1RfMzRfRklFTERfTlVNQkVSID0gMzQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRTaW50NjRMaXN0MzQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUX1BBQ0tFRF8zNV9GSUVMRF9OVU1CRVIgPSAzNTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4+IGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUX0xJU1RfUEFDS0VEXzM2X0ZJRUxEX05VTUJFUiA9IDM2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+PiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuRmxvYXQuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfTElTVF9QQUNLRURfMzdfRklFTERfTlVNQkVSID0gMzc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gZmllbGRJbnQ2NExpc3RQYWNrZWQzNyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfUEFDS0VEXzM4X0ZJRUxEX05VTUJFUiA9IDM4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl9MSVNUX1BBQ0tFRF8zOV9GSUVMRF9OVU1CRVIgPSAzOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBmaWVsZEludDMyTGlzdFBhY2tlZDM5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDY0X0xJU1RfUEFDS0VEXzQwX0ZJRUxEX05VTUJFUiA9IDQwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl9MSVNUX1BBQ0tFRF80MV9GSUVMRF9OVU1CRVIgPSA0MTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfTElTVF9QQUNLRURfNDJfRklFTERfTlVNQkVSID0gNDI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPj4gZmllbGRCb29sTGlzdFBhY2tlZDQyID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbi5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfTElTVF9QQUNLRURfNDNfRklFTERfTlVNQkVSID0gNDM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gZmllbGRVaW50MzJMaXN0UGFja2VkNDMgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fTElTVF9QQUNLRURfNDRfRklFTERfTlVNQkVSID0gNDQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bT4+IGZpZWxkRW51bUxpc3RQYWNrZWQ0NCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyX0xJU1RfUEFDS0VEXzQ1X0ZJRUxEX05VTUJFUiA9IDQ1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0X0xJU1RfUEFDS0VEXzQ2X0ZJRUxEX05VTUJFUiA9IDQ2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl9MSVNUX1BBQ0tFRF80N19GSUVMRF9OVU1CRVIgPSA0NzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0X0xJU1RfUEFDS0VEXzQ4X0ZJRUxEX05VTUJFUiA9IDQ4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMREdST1VQNDlfRklFTERfTlVNQkVSID0gNDk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwNDk+IGZpZWxkR3JvdXA0OSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvMlRlc3RpbmdMaXRlLkZpZWxkR3JvdXA0OS5jbGFzcywKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cDQ5LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMREdST1VQTElTVDUxX0ZJRUxEX05VTUJFUiA9IDUxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8yVGVzdGluZ0xpdGUuRmllbGRHcm91cExpc3Q1MT4+IGZpZWxkR3JvdXBMaXN0NTEgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmNsYXNzLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzJUZXN0aW5nTGl0ZS5GaWVsZEdyb3VwTGlzdDUxLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDQ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXA0OV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNjlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDY5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfUmVxdWlyZWROZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZFJlcXVpcmVkR3JvdXA4OF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZFJlcXVpcmVkR3JvdXA4OF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yRW1wdHlMaXRlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMkVtcHR5TGl0ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfRmllbGRHcm91cDQ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX0ZpZWxkR3JvdXBMaXN0NTFfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sQm9vbDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbERvdWJsZTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbERvdWJsZTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50MzI4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQzMjEzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDY0MTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQzMjE2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDY0MTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCeXRlczE5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCeXRlczE5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RW51bTM4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50NjQ0M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50NjQ0M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDMyNDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50NjQ0OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDMyNTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDY0NTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQm9vbDUyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQm9vbDUyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJ5dGVzNTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRG91YmxlNTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRW51bTU1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRW51bTU1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDMyNTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50NjQ2MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDMyODFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50NjQ4MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDMyODRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50NjQ4NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRW51bTEyM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQzMjEyN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQzMjEyN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDMyMTM1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDY0MTM2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDMyMTUyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDY0MTUzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQm9vbDE1NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRW51bTE1N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQzMjE3OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQzMjE3OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDMyMTgzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDY0MTg0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDMyMTg2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RG91YmxlMTkwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDMyMjAwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDY0MjAxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDMyMjAzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDY0MjA0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4tY29tL2dvb2dsZS9wcm90b2J1Zi9wcm90bzJfbWVzc2FnZV9saXQiICsKICAgICAgImUucHJvdG9cMDIyXDAzMnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlXCJcMzAwXDAzNFxuXDAyMSIgKwogICAgICAiUHJvdG8yTWVzc2FnZUxpdGVcMDIyXDAyNlxuXDAxNmZpZWxkX2RvdWJsZV8xXDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDFcMDIyXDAyNVxuXHJmaWVsZF9mbG9hdF8yXDAzMFwwMDIgXDAwMShcMDAyXDAyMlwwMjVcblxyZmllbGRfaW50NjRfIiArCiAgICAgICIzXDAzMFwwMDMgXDAwMShcMDAzXDAyMlwwMjZcblwwMTZmaWVsZF91aW50NjRfNFwwMzBcMDA0IFwwMDEoXDAwNFwwMjJcMDI1XG5ccmZpZWxkIiArCiAgICAgICJfaW50MzJfNVwwMzBcMDA1IFwwMDEoXDAwNVwwMjJcMDI3XG5cMDE3ZmllbGRfZml4ZWQ2NF82XDAzMFwwMDYgXDAwMShcMDA2XDAyMiIgKwogICAgICAiXDAyN1xuXDAxN2ZpZWxkX2ZpeGVkMzJfN1wwMzBcMDA3IFwwMDEoXDAwN1wwMjJcMDI0XG5cMDE0ZmllbGRfYm9vbF84IiArCiAgICAgICJcMDMwXDAxMCBcMDAxKFwwMTBcMDIyXDAyNlxuXDAxNmZpZWxkX3N0cmluZ185XDAzMFx0IFwwMDEoXHRcMDIyR1xuXDAyMGZpZWxkXyIgKwogICAgICAibWVzc2FnZV8xMFwwMzBcbiBcMDAxKFwwMTMyLS5wcm90b2J1Zi5leHBlcmltZW50YWwiICsKICAgICAgIi5saXRlLlByb3RvMk1lc3NhZ2VMaXRlXDAyMlwwMjZcblwwMTZmaWVsZF9ieXRlc18xIiArCiAgICAgICIxXDAzMFwwMTMgXDAwMShcMDE0XDAyMlwwMjdcblwwMTdmaWVsZF91aW50MzJfMTJcMDMwXDAxNCBcMDAxKFxyXDAyMk1cblxyZmllbCIgKwogICAgICAiZF9lbnVtXzEzXDAzMFxyIFwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW1cMDIyXDAzMVxuXDAyMWZpZWxkIiArCiAgICAgICJfc2ZpeGVkMzJfMTRcMDMwXDAxNiBcMDAxKFwwMTdcMDIyXDAzMVxuXDAyMWZpZWxkX3NmaXhlZDY0XzE1XDAzMCIgKwogICAgICAiXDAxNyBcMDAxKFwwMjBcMDIyXDAyN1xuXDAxN2ZpZWxkX3NpbnQzMl8xNlwwMzBcMDIwIFwwMDEoXDAyMVwwMjJcMDI3XG5cMDE3ZmllbGRfIiArCiAgICAgICJzaW50NjRfMTdcMDMwXDAyMSBcMDAxKFwwMjJcMDIyIFxuXDAyNGZpZWxkX2RvdWJsZV9saXN0XzE4XDAzMCIgKwogICAgICAiXDAyMiBcMDAzKFwwMDFCXDAwMlwwMjBcMDAwXDAyMlwwMzdcblwwMjNmaWVsZF9mbG9hdF9saXN0XzE5XDAzMFwwMjMgXDAwMyhcMDAyQlwwMDIiICsKICAgICAgIlwwMjBcMDAwXDAyMlwwMzdcblwwMjNmaWVsZF9pbnQ2NF9saXN0XzIwXDAzMFwwMjQgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMFwwMjIgXG5cMDI0ZiIgKwogICAgICAiaWVsZF91aW50NjRfbGlzdF8yMVwwMzBcMDI1IFwwMDMoXDAwNEJcMDAyXDAyMFwwMDBcMDIyXDAzN1xuXDAyM2ZpZWxkX2kiICsKICAgICAgIm50MzJfbGlzdF8yMlwwMzBcMDI2IFwwMDMoXDAwNUJcMDAyXDAyMFwwMDBcMDIyIVxuXDAyNWZpZWxkX2ZpeGVkNjRfIiArCiAgICAgICJsaXN0XzIzXDAzMFwwMjcgXDAwMyhcMDA2QlwwMDJcMDIwXDAwMFwwMjIhXG5cMDI1ZmllbGRfZml4ZWQzMl9saXN0XyIgKwogICAgICAiMjRcMDMwXDAzMCBcMDAzKFwwMDdCXDAwMlwwMjBcMDAwXDAyMlwwMzZcblwwMjJmaWVsZF9ib29sX2xpc3RfMjVcMDMwXDAzMSBcMDAzKFwwMTAiICsKICAgICAgIkJcMDAyXDAyMFwwMDBcMDIyIFxuXDAyNGZpZWxkX3N0cmluZ19saXN0XzI2XDAzMFwwMzIgXDAwMyhcdEJcMDAyXDAyMFwwMDBcMDIyUCIgKwogICAgICAiXG5cMDI1ZmllbGRfbWVzc2FnZV9saXN0XzI3XDAzMFwwMzMgXDAwMyhcMDEzMi0ucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZUJcMDAyXDAyMFwwMDAiICsKICAgICAgIlwwMjJcMDM3XG5cMDIzZmllbGRfYnl0ZXNfbGlzdF8yOFwwMzBcMDM0IFwwMDMoXDAxNEJcMDAyXDAyMFwwMDBcMDIyIFxuXDAyNGZpZSIgKwogICAgICAibGRfdWludDMyX2xpc3RfMjlcMDMwXDAzNSBcMDAzKFxyQlwwMDJcMDIwXDAwMFwwMjJWXG5cMDIyZmllbGRfZW51IiArCiAgICAgICJtX2xpc3RfMzBcMDMwXDAzNiBcMDAzKFwwMTYyNi5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJsaXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtQlwwMDJcMDIwXDAwMFwwMjJcIlxuXDAyNmYiICsKICAgICAgImllbGRfc2ZpeGVkMzJfbGlzdF8zMVwwMzBcMDM3IFwwMDMoXDAxN0JcMDAyXDAyMFwwMDBcMDIyXCJcblwwMjZmaWVsZCIgKwogICAgICAiX3NmaXhlZDY0X2xpc3RfMzJcMDMwICBcMDAzKFwwMjBCXDAwMlwwMjBcMDAwXDAyMiBcblwwMjRmaWVsZF9zaW4iICsKICAgICAgInQzMl9saXN0XzMzXDAzMCEgXDAwMyhcMDIxQlwwMDJcMDIwXDAwMFwwMjIgXG5cMDI0ZmllbGRfc2ludDY0X2xpIiArCiAgICAgICJzdF8zNFwwMzBcIiBcMDAzKFwwMjJCXDAwMlwwMjBcMDAwXDAyMlwnXG5cMDMzZmllbGRfZG91YmxlX2xpc3RfcGFjIiArCiAgICAgICJrZWRfMzVcMDMwIyBcMDAzKFwwMDFCXDAwMlwwMjBcMDAxXDAyMiZcblwwMzJmaWVsZF9mbG9hdF9saXN0X3BhYyIgKwogICAgICAia2VkXzM2XDAzMCQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMVwwMjImXG5cMDMyZmllbGRfaW50NjRfbGlzdF9wYWMiICsKICAgICAgImtlZF8zN1wwMzAlIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXCdcblwwMzNmaWVsZF91aW50NjRfbGlzdF9wYSIgKwogICAgICAiY2tlZF8zOFwwMzAmIFwwMDMoXDAwNEJcMDAyXDAyMFwwMDFcMDIyJlxuXDAzMmZpZWxkX2ludDMyX2xpc3RfcGEiICsKICAgICAgImNrZWRfMzlcMDMwXCcgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjIoXG5cMDM0ZmllbGRfZml4ZWQ2NF9saXN0XyIgKwogICAgICAicGFja2VkXzQwXDAzMCggXDAwMyhcMDA2QlwwMDJcMDIwXDAwMVwwMjIoXG5cMDM0ZmllbGRfZml4ZWQzMl9saXMiICsKICAgICAgInRfcGFja2VkXzQxXDAzMCkgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMVwwMjIlXG5cMDMxZmllbGRfYm9vbF9saXN0IiArCiAgICAgICJfcGFja2VkXzQyXDAzMCogXDAwMyhcMDEwQlwwMDJcMDIwXDAwMVwwMjJcJ1xuXDAzM2ZpZWxkX3VpbnQzMl9saXMiICsKICAgICAgInRfcGFja2VkXzQzXDAzMCsgXDAwMyhcckJcMDAyXDAyMFwwMDFcMDIyXVxuXDAzMWZpZWxkX2VudW1fbGlzdCIgKwogICAgICAiX3BhY2tlZF80NFwwMzAsIFwwMDMoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW1CXDAwMlwwMjBcMDAxXDAyMilcblwwMzUiICsKICAgICAgImZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1XDAzMC0gXDAwMyhcMDE3QlwwMDJcMDIwXDAwMVwwMjIiICsKICAgICAgIilcblwwMzVmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NlwwMzAuIFwwMDMoXDAyMEJcMDAyIiArCiAgICAgICJcMDIwXDAwMVwwMjJcJ1xuXDAzM2ZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80N1wwMzAvIFwwMDMoXDAyMUIiICsKICAgICAgIlwwMDJcMDIwXDAwMVwwMjJcJ1xuXDAzM2ZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OFwwMzAwIFwwMDMoXDAyMiIgKwogICAgICAiQlwwMDJcMDIwXDAwMVwwMjJQXG5cMDE0ZmllbGRncm91cDQ5XDAzMDEgXDAwMShcbjI6LnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuRmllbGRHIiArCiAgICAgICJyb3VwNDlcMDIyWFxuXDAyMGZpZWxkZ3JvdXBsaXN0NTFcMDMwMyBcMDAzKFxuMj4ucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS4iICsKICAgICAgIkZpZWxkR3JvdXBMaXN0NTFcMDIyXDAzMVxuXDAxN2ZpZWxkX2RvdWJsZV81M1wwMzA1IFwwMDEoIiArCiAgICAgICJcMDAxSFwwMDBcMDIyXDAzMFxuXDAxNmZpZWxkX2Zsb2F0XzU0XDAzMDYgXDAwMShcMDAySFwwMDBcMDIyXDAzMFxuXDAxNmZpZWxkX2kiICsKICAgICAgIm50NjRfNTVcMDMwNyBcMDAxKFwwMDNIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfdWludDY0XzU2XDAzMDggXDAwMShcMDA0IiArCiAgICAgICJIXDAwMFwwMjJcMDMwXG5cMDE2ZmllbGRfaW50MzJfNTdcMDMwOSBcMDAxKFwwMDVIXDAwMFwwMjJcMDMyXG5cMDIwZmllbGRfZmkiICsKICAgICAgInhlZDY0XzU4XDAzMDogXDAwMShcMDA2SFwwMDBcMDIyXDAzMlxuXDAyMGZpZWxkX2ZpeGVkMzJfNTlcMDMwOyBcMDAxIiArCiAgICAgICIoXDAwN0hcMDAwXDAyMlwwMjdcblxyZmllbGRfYm9vbF82MFwwMzA8IFwwMDEoXDAxMEhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF9zIiArCiAgICAgICJ0cmluZ182MVwwMzA9IFwwMDEoXHRIXDAwMFwwMjJJXG5cMDIwZmllbGRfbWVzc2FnZV82MlwwMzA+IFwwMDEiICsKICAgICAgIihcMDEzMi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWUiICsKICAgICAgInNzYWdlTGl0ZUhcMDAwXDAyMlwwMzBcblwwMTZmaWVsZF9ieXRlc182M1wwMzA/IFwwMDEoXDAxNEhcMDAwXDAyMlwwMzFcbiIgKwogICAgICAiXDAxN2ZpZWxkX3VpbnQzMl82NFwwMzBAIFwwMDEoXHJIXDAwMFwwMjJcMDMzXG5cMDIxZmllbGRfc2ZpeGVkIiArCiAgICAgICIzMl82NVwwMzBBIFwwMDEoXDAxN0hcMDAwXDAyMlwwMzNcblwwMjFmaWVsZF9zZml4ZWQ2NF82NlwwMzBCIFwwMDEoXDAyMCIgKwogICAgICAiSFwwMDBcMDIyXDAzMVxuXDAxN2ZpZWxkX3NpbnQzMl82N1wwMzBDIFwwMDEoXDAyMUhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF9zIiArCiAgICAgICJpbnQ2NF82OFwwMzBEIFwwMDEoXDAyMkhcMDAwXDAyMlJcblwwMTRmaWVsZGdyb3VwNjlcMDMwRSBcMDAxKFxuMjoiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWciICsKICAgICAgImVMaXRlLkZpZWxkR3JvdXA2OUhcMDAwXDAyMiBcblwwMzBmaWVsZF9yZXF1aXJlZF9kIiArCiAgICAgICJvdWJsZV83MVwwMzBHIFwwMDIoXDAwMVwwMjJcMDM3XG5cMDI3ZmllbGRfcmVxdWlyZWRfZmxvYXRfNyIgKwogICAgICAiMlwwMzBIIFwwMDIoXDAwMlwwMjJcMDM3XG5cMDI3ZmllbGRfcmVxdWlyZWRfaW50NjRfNzNcMDMwSSBcMDAyKFwwMDMiICsKICAgICAgIlwwMjIgXG5cMDMwZmllbGRfcmVxdWlyZWRfdWludDY0Xzc0XDAzMEogXDAwMihcMDA0XDAyMlwwMzdcblwwMjdmaSIgKwogICAgICAiZWxkX3JlcXVpcmVkX2ludDMyXzc1XDAzMEsgXDAwMihcMDA1XDAyMiFcblwwMzFmaWVsZF9yZXEiICsKICAgICAgInVpcmVkX2ZpeGVkNjRfNzZcMDMwTCBcMDAyKFwwMDZcMDIyIVxuXDAzMWZpZWxkX3JlcXVpcmVkIiArCiAgICAgICJfZml4ZWQzMl83N1wwMzBNIFwwMDIoXDAwN1wwMjJcMDM2XG5cMDI2ZmllbGRfcmVxdWlyZWRfYm9vbCIgKwogICAgICAiXzc4XDAzME4gXDAwMihcMDEwXDAyMiBcblwwMzBmaWVsZF9yZXF1aXJlZF9zdHJpbmdfNzlcMDMwTyAiICsKICAgICAgIlwwMDIoXHRcMDIyZlxuXDAzMWZpZWxkX3JlcXVpcmVkX21lc3NhZ2VfODBcMDMwUCBcMDAyKFwwMTMyQyIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZyIgKwogICAgICAiZUxpdGUuUmVxdWlyZWROZXN0ZWRNZXNzYWdlXDAyMlwwMzdcblwwMjdmaWVsZF9yZXEiICsKICAgICAgInVpcmVkX2J5dGVzXzgxXDAzMFEgXDAwMihcMDE0XDAyMiBcblwwMzBmaWVsZF9yZXF1aXJlZF91IiArCiAgICAgICJpbnQzMl84MlwwMzBSIFwwMDIoXHJcMDIyVlxuXDAyNmZpZWxkX3JlcXVpcmVkX2VudW1fODMiICsKICAgICAgIlwwMzBTIFwwMDIoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3QiICsKICAgICAgIm8yTWVzc2FnZUxpdGUuVGVzdEVudW1cMDIyXCJcblwwMzJmaWVsZF9yZXF1aXJlZCIgKwogICAgICAiX3NmaXhlZDMyXzg0XDAzMFQgXDAwMihcMDE3XDAyMlwiXG5cMDMyZmllbGRfcmVxdWlyZWRfc2ZpIiArCiAgICAgICJ4ZWQ2NF84NVwwMzBVIFwwMDIoXDAyMFwwMjIgXG5cMDMwZmllbGRfcmVxdWlyZWRfc2ludDMyXyIgKwogICAgICAiODZcMDMwViBcMDAyKFwwMjFcMDIyIFxuXDAzMGZpZWxkX3JlcXVpcmVkX3NpbnQ2NF84N1wwMzBXIFwwMDIiICsKICAgICAgIihcMDIyXDAyMmBcblwwMjRmaWVsZHJlcXVpcmVkZ3JvdXA4OFwwMzBYIFwwMDIoXG4yQi5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLiIgKwogICAgICAiRmllbGRSZXF1aXJlZEdyb3VwODhcMDMyJlxuXDAxNEZpZWxkR3JvdXA0OVwwMjJcMDI2XG5cMDE2IiArCiAgICAgICJmaWVsZF9pbnQzMl81MFwwMzAyIFwwMDEoXDAwNVwwMzIqXG5cMDIwRmllbGRHcm91cExpc3Q1MSIgKwogICAgICAiXDAyMlwwMjZcblwwMTZmaWVsZF9pbnQzMl81MlwwMzA0IFwwMDEoXDAwNVwwMzImXG5cMDE0RmllbGRHcm91cDY5IiArCiAgICAgICJcMDIyXDAyNlxuXDAxNmZpZWxkX2ludDMyXzcwXDAzMEYgXDAwMShcMDA1XDAzMiZcblwwMjVSZXF1aXJlZE5lc3QiICsKICAgICAgImVkTWVzc2FnZVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDEgXDAwMShcMDA1XDAzMi5cblwwMjRGaWVsZFJlcXVpcmUiICsKICAgICAgImRHcm91cDg4XDAyMlwwMjZcblwwMTZmaWVsZF9pbnQzMl84OVwwMzBZIFwwMDEoXDAwNVwiJlxuXDAxMFRlc3QiICsKICAgICAgIkVudW1cMDIyXDAxMFxuXDAwNFpFUk9cMDIwXDAwMFwwMjJcMDA3XG5cMDAzT05FXDAyMFwwMDFcMDIyXDAwN1xuXDAwM1RXT1wwMjBcMDAyQlwwMTRcblxudGVzdCIgKwogICAgICAiX29uZW9mXCJcMDIxXG5cMDE3UHJvdG8yRW1wdHlMaXRlXCIrXG5cMDM3UHJvdG8yTWVzc2EiICsKICAgICAgImdlTGl0ZVdpdGhFeHRlbnNpb25zKlwwMTBcMDEwXDAwMVwwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwiJlxuXDAxNEZpZWxkRyIgKwogICAgICAicm91cDQ5XDAyMlwwMjZcblwwMTZmaWVsZF9pbnQzMl81MFwwMzAyIFwwMDEoXDAwNVwiKlxuXDAyMEZpZWxkRyIgKwogICAgICAicm91cExpc3Q1MVwwMjJcMDI2XG5cMDE2ZmllbGRfaW50MzJfNTJcMDMwNCBcMDAxKFwwMDVcIlwyNDZcMjU3XDAwMlxuXDAzMSIgKwogICAgICAiUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc1wwMjJrXG5cMDI1ZmllbGRfbWFwX2IiICsKICAgICAgIm9vbF9ib29sXzFcMDMwXDAwMSBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW50YWwiICsKICAgICAgIi5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIkJvb2xCb29sMUVudHJ5XDAyMm1cblwwMjZmaWVsZF9tYXBfYm9vbF9ieXRlc18yIiArCiAgICAgICJcMDMwXDAwMiBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90IiArCiAgICAgICJvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBCb29sQnl0ZXMyIiArCiAgICAgICJFbnRyeVwwMjJvXG5cMDI3ZmllbGRfbWFwX2Jvb2xfZG91YmxlXzNcMDMwXDAwMyBcMDAzKFwwMTMyTiIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZyIgKwogICAgICAiZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvb2xEb3VibGUzRW50cnlcMDIyayIgKwogICAgICAiXG5cMDI1ZmllbGRfbWFwX2Jvb2xfZW51bV80XDAzMFwwMDQgXDAwMyhcMDEzMkwucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBCb29sRW51bTRFbnRyeVwwMjJxXG5cMDMwZmllbGRfbWFwIiArCiAgICAgICJfYm9vbF9maXhlZDMyXzVcMDMwXDAwNSBcMDAzKFwwMTMyTy5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcEJvb2xGaXhlZDMyNUVudHJ5XDAyMnFcblwwMzBmaWVsZF9tYXBfYm9vbCIgKwogICAgICAiX2ZpeGVkNjRfNlwwMzBcMDA2IFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiQm9vbEZpeGVkNjQ2RW50cnlcMDIybVxuXDAyNmZpZWxkX21hcF9ib29sX2Zsb2EiICsKICAgICAgInRfN1wwMzBcMDA3IFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlAiICsKICAgICAgInJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvb2xGbG8iICsKICAgICAgImF0N0VudHJ5XDAyMm1cblwwMjZmaWVsZF9tYXBfYm9vbF9pbnQzMl84XDAzMFwwMTAgXDAwMyhcMDEzIiArCiAgICAgICIyTS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzIiArCiAgICAgICJhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBCb29sSW50MzI4RW50cnlcMDIyIiArCiAgICAgICJtXG5cMDI2ZmllbGRfbWFwX2Jvb2xfaW50NjRfOVwwMzBcdCBcMDAzKFwwMTMyTS5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeVwwMjJzXG5cMDMxZmllbGRfIiArCiAgICAgICJtYXBfYm9vbF9tZXNzYWdlXzEwXDAzMFxuIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXAiICsKICAgICAgIl9ib29sX3NmaXhlZDMyXzExXDAzMFwwMTMgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXBfIiArCiAgICAgICJib29sX3NmaXhlZDY0XzEyXDAzMFwwMTQgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBCb29sU2ZpeGVkNjQxMkVudHJ5XDAyMnFcblwwMzBmaWVsZF9tYXBfYiIgKwogICAgICAib29sX3NpbnQzMl8xM1wwMzBcciBcMDAzKFwwMTMyTy5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGQiICsKICAgICAgIk1hcEJvb2xTaW50MzIxM0VudHJ5XDAyMnFcblwwMzBmaWVsZF9tYXBfYm9vbF9zIiArCiAgICAgICJpbnQ2NF8xNFwwMzBcMDE2IFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5sIiArCiAgICAgICJpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvIiArCiAgICAgICJvbFNpbnQ2NDE0RW50cnlcMDIycVxuXDAzMGZpZWxkX21hcF9ib29sX3N0cmluZyIgKwogICAgICAiXzE1XDAzMFwwMTcgXDAwMyhcMDEzMk8ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUCIgKwogICAgICAicm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwQm9vbFN0ciIgKwogICAgICAiaW5nMTVFbnRyeVwwMjJxXG5cMDMwZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2XDAzMFwwMjAiICsKICAgICAgIiBcMDAzKFwwMTMyTy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzIiICsKICAgICAgIk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBCb29sVWludDMyMTYiICsKICAgICAgIkVudHJ5XDAyMnFcblwwMzBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTdcMDMwXDAyMSBcMDAzKFwwMTMyIiArCiAgICAgICJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhIiArCiAgICAgICJnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5IiArCiAgICAgICJcMDIyc1xuXDAzMWZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMThcMDMwXDAyMiBcMDAzKFwwMTMyUC5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaSIgKwogICAgICAidGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeVwwMjJ1XG4iICsKICAgICAgIlwwMzJmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOVwwMzBcMDIzIFwwMDMoXDAxMzJRLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeVwwMjJ3XG5cMDMzIiArCiAgICAgICJmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjBcMDMwXDAyNCBcMDAzKFwwMTMyUi5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5XDAyMnNcbiIgKwogICAgICAiXDAzMWZpZWxkX21hcF9maXhlZDMyX2VudW1fMjFcMDMwXDAyNSBcMDAzKFwwMTMyUC5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlVyIgKwogICAgICAiaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyeVwwMjJ5XG5cMDM0ZmkiICsKICAgICAgImVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyXDAzMFwwMjYgXDAwMyhcMDEzMlMucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlcMDIyeVxuIiArCiAgICAgICJcMDM0ZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yM1wwMzBcMDI3IFwwMDMoXDAxMzJTLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpIiArCiAgICAgICJ0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5IiArCiAgICAgICJcMDIydVxuXDAzMmZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0XDAzMFwwMzAgXDAwMyhcMDEzMlEucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHJ5XDAyMiIgKwogICAgICAidVxuXDAzMmZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1XDAzMFwwMzEgXDAwMyhcMDEzMlEucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGkiICsKICAgICAgInRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5XDAyMnUiICsKICAgICAgIlxuXDAzMmZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2XDAzMFwwMzIgXDAwMyhcMDEzMlEucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0IiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5XDAyMnlcbiIgKwogICAgICAiXDAzNGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjdcMDMwXDAzMyBcMDAzKFwwMTMyUy5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaSIgKwogICAgICAidGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdFbnRyeSIgKwogICAgICAiXDAyMntcblwwMzVmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOFwwMzBcMDM0IFwwMDMoXDAxMzIiICsKICAgICAgIlQucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2EiICsKICAgICAgImdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgiICsKICAgICAgIkVudHJ5XDAyMntcblwwMzVmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOVwwMzBcMDM1IiArCiAgICAgICIgXDAwMyhcMDEzMlQucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yIiArCiAgICAgICJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMlNmaXhlIiArCiAgICAgICJkNjQyOUVudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMyIgKwogICAgICAiMFwwMzBcMDM2IFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlBybyIgKwogICAgICAidG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJTaSIgKwogICAgICAibnQzMjMwRW50cnlcMDIyd1xuXDAzM2ZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8iICsKICAgICAgIjMxXDAzMFwwMzcgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHIiICsKICAgICAgIm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMlMiICsKICAgICAgImludDY0MzFFbnRyeVwwMjJ3XG5cMDMzZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nIiArCiAgICAgICJfMzJcMDMwICBcMDAzKFwwMTMyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5QIiArCiAgICAgICJyb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyIiArCiAgICAgICJTdHJpbmczMkVudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfZml4ZWQzMl91aW50MyIgKwogICAgICAiMl8zM1wwMzAhIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMyIgKwogICAgICAiMlVpbnQzMjMzRW50cnlcMDIyd1xuXDAzM2ZpZWxkX21hcF9maXhlZDMyX3VpbnQiICsKICAgICAgIjY0XzM0XDAzMFwiIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlIiArCiAgICAgICIuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkIiArCiAgICAgICIzMlVpbnQ2NDM0RW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9maXhlZDY0X2JvbyIgKwogICAgICAibF8zNVwwMzAjIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNiIgKwogICAgICAiNEJvb2wzNUVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18iICsKICAgICAgIjM2XDAzMCQgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHIiICsKICAgICAgIm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEIiICsKICAgICAgInl0ZXMzNkVudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfIiArCiAgICAgICIzN1wwMzAlIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByIiArCiAgICAgICJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjREIiArCiAgICAgICJvdWJsZTM3RW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9maXhlZDY0X2VudW1fMyIgKwogICAgICAiOFwwMzAmIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlBybyIgKwogICAgICAidG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjRFbiIgKwogICAgICAidW0zOEVudHJ5XDAyMnlcblwwMzRmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzMiICsKICAgICAgIjlcMDMwXCcgXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEZpIiArCiAgICAgICJ4ZWQzMjM5RW50cnlcMDIyeVxuXDAzNGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNiIgKwogICAgICAiNF80MFwwMzAoIFwwMDMoXDAxMzJTLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNiIgKwogICAgICAiNEZpeGVkNjQ0MEVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9mbG8iICsKICAgICAgImF0XzQxXDAzMCkgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUiICsKICAgICAgIi5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQiICsKICAgICAgIjY0RmxvYXQ0MUVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzIiArCiAgICAgICIyXzQyXDAzMCogXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuIiArCiAgICAgICJQcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2IiArCiAgICAgICI0SW50MzI0MkVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NCIgKwogICAgICAiXzQzXDAzMCsgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUCIgKwogICAgICAicm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NCIgKwogICAgICAiSW50NjQ0M0VudHJ5XDAyMnlcblwwMzRmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWciICsKICAgICAgImVfNDRcMDMwLCBcMDAzKFwwMTMyUy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS4iICsKICAgICAgIlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDYiICsKICAgICAgIjRNZXNzYWdlNDRFbnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX2ZpeGVkNjRfc2ZpIiArCiAgICAgICJ4ZWQzMl80NVwwMzAtIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5sIiArCiAgICAgICJpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpIiArCiAgICAgICJ4ZWQ2NFNmaXhlZDMyNDVFbnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX2ZpeGVkNiIgKwogICAgICAiNF9zZml4ZWQ2NF80NlwwMzAuIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbiIgKwogICAgICAidGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZCIgKwogICAgICAiTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeVwwMjJ3XG5cMDMzZmllbGRfbWFwX2YiICsKICAgICAgIml4ZWQ2NF9zaW50MzJfNDdcMDMwLyBcMDAzKFwwMTMyUi5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmkiICsKICAgICAgImVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfIiArCiAgICAgICJmaXhlZDY0X3NpbnQ2NF80OFwwMzAwIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GIiArCiAgICAgICJpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlcMDIyd1xuXDAzM2ZpZWxkX21hcCIgKwogICAgICAiX2ZpeGVkNjRfc3RyaW5nXzQ5XDAzMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLiIgKwogICAgICAiRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeVwwMjJ3XG5cMDMzZmllbGRfbWEiICsKICAgICAgInBfZml4ZWQ2NF91aW50MzJfNTBcMDMwMiBcMDAzKFwwMTMyUi5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMiICsKICAgICAgIi5GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5XDAyMndcblwwMzNmaWVsZF9tIiArCiAgICAgICJhcF9maXhlZDY0X3VpbnQ2NF81MVwwMzAzIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlcMDIyb1xuXDAyN2ZpZWxkXyIgKwogICAgICAibWFwX2ludDMyX2Jvb2xfNTJcMDMwNCBcMDAzKFwwMTMyTi5wcm90b2J1Zi5leHBlciIgKwogICAgICAiaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcEludDMyQm9vbDUyRW50cnlcMDIycVxuXDAzMGZpZWxkX21hcF9pbnQiICsKICAgICAgIjMyX2J5dGVzXzUzXDAzMDUgXDAwMyhcMDEzMk8ucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBJbnQzMkJ5dGVzNTNFbnRyeVwwMjJzXG5cMDMxZmllbGRfbWFwX2ludDMyX2RvIiArCiAgICAgICJ1YmxlXzU0XDAzMDYgXDAwMyhcMDEzMlAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpIiArCiAgICAgICJ0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50IiArCiAgICAgICIzMkRvdWJsZTU0RW50cnlcMDIyb1xuXDAyN2ZpZWxkX21hcF9pbnQzMl9lbnVtXyIgKwogICAgICAiNTVcMDMwNyBcMDAzKFwwMTMyTi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5QciIgKwogICAgICAib3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkVudSIgKwogICAgICAibTU1RW50cnlcMDIydVxuXDAzMmZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2XDAzMDgiICsKICAgICAgIiBcMDAzKFwwMTMyUS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzIiICsKICAgICAgIk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkZpeGVkMzIiICsKICAgICAgIjU2RW50cnlcMDIydVxuXDAzMmZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3XDAzMDkgIiArCiAgICAgICJcMDAzKFwwMTMyUS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNIiArCiAgICAgICJlc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkZpeGVkNjQ1IiArCiAgICAgICI3RW50cnlcMDIycVxuXDAzMGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OFwwMzA6IFwwMDMoXDAxMyIgKwogICAgICAiMk8ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzcyIgKwogICAgICAiYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50MzJGbG9hdDU4RW50ciIgKwogICAgICAieVwwMjJxXG5cMDMwZmllbGRfbWFwX2ludDMyX2ludDMyXzU5XDAzMDsgXDAwMyhcMDEzMk8ucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGkiICsKICAgICAgInRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkludDMyNTlFbnRyeVwwMjJxXG5cMDMwIiArCiAgICAgICJmaWVsZF9tYXBfaW50MzJfaW50NjRfNjBcMDMwPCBcMDAzKFwwMTMyTy5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0IiArCiAgICAgICJoTWFwcy5GaWVsZE1hcEludDMySW50NjQ2MEVudHJ5XDAyMnVcblwwMzJmaWVsZCIgKwogICAgICAiX21hcF9pbnQzMl9tZXNzYWdlXzYxXDAzMD0gXDAwMyhcMDEzMlEucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5XDAyMndcblwwMzNmaWVsZF8iICsKICAgICAgIm1hcF9pbnQzMl9zZml4ZWQzMl82MlwwMzA+IFwwMDMoXDAxMzJSLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlcMDIyd1xuXDAzM2ZpZWxkIiArCiAgICAgICJfbWFwX2ludDMyX3NmaXhlZDY0XzYzXDAzMD8gXDAwMyhcMDEzMlIucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNIiArCiAgICAgICJhcHMuRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeVwwMjJzXG5cMDMxZmllbCIgKwogICAgICAiZF9tYXBfaW50MzJfc2ludDMyXzY0XDAzMEAgXDAwMyhcMDEzMlAucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlcMDIyc1xuXDAzMWZpZWxkX20iICsKICAgICAgImFwX2ludDMyX3NpbnQ2NF82NVwwMzBBIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5XDAyMnNcblwwMzFmaWVsZF9tYXBfIiArCiAgICAgICJpbnQzMl9zdHJpbmdfNjZcMDMwQiBcMDAzKFwwMTMyUC5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcEludDMyU3RyaW5nNjZFbnRyeVwwMjJzXG5cMDMxZmllbGRfbWFwX2ludCIgKwogICAgICAiMzJfdWludDMyXzY3XDAzMEMgXDAwMyhcMDEzMlAucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBJbnQzMlVpbnQzMjY3RW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9pbnQzMl8iICsKICAgICAgInVpbnQ2NF82OFwwMzBEIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEkiICsKICAgICAgIm50MzJVaW50NjQ2OEVudHJ5XDAyMm9cblwwMjdmaWVsZF9tYXBfaW50NjRfYm9vIiArCiAgICAgICJsXzY5XDAzMEUgXDAwMyhcMDEzMk4ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuIiArCiAgICAgICJQcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRCIiArCiAgICAgICJvb2w2OUVudHJ5XDAyMnFcblwwMzBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzBcMDMwRiIgKwogICAgICAiIFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMiIgKwogICAgICAiTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDY0Qnl0ZXM3MCIgKwogICAgICAiRW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzFcMDMwRyBcMDAzKFwwMTMiICsKICAgICAgIjJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3MiICsKICAgICAgImFnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDY0RG91YmxlNzFFbnQiICsKICAgICAgInJ5XDAyMm9cblwwMjdmaWVsZF9tYXBfaW50NjRfZW51bV83MlwwMzBIIFwwMDMoXDAxMzJOLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpIiArCiAgICAgICJ0ZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeVwwMjJ1XG5cMDMyZiIgKwogICAgICAiaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83M1wwMzBJIFwwMDMoXDAxMzJRLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaSIgKwogICAgICAidGhNYXBzLkZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeVwwMjJ1XG5cMDMyZmkiICsKICAgICAgImVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NFwwMzBKIFwwMDMoXDAxMzJRLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXQiICsKICAgICAgImhNYXBzLkZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeVwwMjJxXG5cMDMwZmllIiArCiAgICAgICJsZF9tYXBfaW50NjRfZmxvYXRfNzVcMDMwSyBcMDAzKFwwMTMyTy5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5XDAyMnFcblwwMzBmaWVsZF9tYSIgKwogICAgICAicF9pbnQ2NF9pbnQzMl83NlwwMzBMIFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaSIgKwogICAgICAibWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwSW50NjRJbnQzMjc2RW50cnlcMDIycVxuXDAzMGZpZWxkX21hcF9pbnQiICsKICAgICAgIjY0X2ludDY0Xzc3XDAzME0gXDAwMyhcMDEzMk8ucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBJbnQ2NEludDY0NzdFbnRyeVwwMjJ1XG5cMDMyZmllbGRfbWFwX2ludDY0X21lIiArCiAgICAgICJzc2FnZV83OFwwMzBOIFwwMDMoXDAxMzJRLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5sIiArCiAgICAgICJpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEluIiArCiAgICAgICJ0NjRNZXNzYWdlNzhFbnRyeVwwMjJ3XG5cMDMzZmllbGRfbWFwX2ludDY0X3NmaSIgKwogICAgICAieGVkMzJfNzlcMDMwTyBcMDAzKFwwMTMyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubCIgKwogICAgICAiaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbiIgKwogICAgICAidDY0U2ZpeGVkMzI3OUVudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfaW50NjRfc2YiICsKICAgICAgIml4ZWQ2NF84MFwwMzBQIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEkiICsKICAgICAgIm50NjRTZml4ZWQ2NDgwRW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9pbnQ2NF9zIiArCiAgICAgICJpbnQzMl84MVwwMzBRIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5sIiArCiAgICAgICJpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEluIiArCiAgICAgICJ0NjRTaW50MzI4MUVudHJ5XDAyMnNcblwwMzFmaWVsZF9tYXBfaW50NjRfc2ludCIgKwogICAgICAiNjRfODJcMDMwUiBcMDAzKFwwMTMyUC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZSIgKwogICAgICAiLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NCIgKwogICAgICAiU2ludDY0ODJFbnRyeVwwMjJzXG5cMDMxZmllbGRfbWFwX2ludDY0X3N0cmluZ18iICsKICAgICAgIjgzXDAzMFMgXDAwMyhcMDEzMlAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHIiICsKICAgICAgIm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRTdHIiICsKICAgICAgImluZzgzRW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9pbnQ2NF91aW50MzJfODRcMDMwIiArCiAgICAgICJUIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvIiArCiAgICAgICIyTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDY0VWludDMyIiArCiAgICAgICI4NEVudHJ5XDAyMnNcblwwMzFmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1XDAzMFUgXDAwMyIgKwogICAgICAiKFwwMTMyUC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZSIgKwogICAgICAic3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RSIgKwogICAgICAibnRyeVwwMjJ1XG5cMDMyZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODZcMDMwViBcMDAzKFwwMTMiICsKICAgICAgIjJRLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3MiICsKICAgICAgImFnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW4iICsKICAgICAgInRyeVwwMjJ3XG5cMDMzZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3XDAzMFcgXDAwMyhcMDEzIiArCiAgICAgICIyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzIiArCiAgICAgICJhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFIiArCiAgICAgICJudHJ5XDAyMnlcblwwMzRmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4XDAzMFggXDAwMyIgKwogICAgICAiKFwwMTMyUy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZSIgKwogICAgICAic3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkRvdWJsZSIgKwogICAgICAiODhFbnRyeVwwMjJ1XG5cMDMyZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODlcMDMwWSAiICsKICAgICAgIlwwMDMoXDAxMzJRLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk0iICsKICAgICAgImVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyRW51bTgiICsKICAgICAgIjlFbnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTBcMDMwIiArCiAgICAgICJaIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvIiArCiAgICAgICIyTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyRml4IiArCiAgICAgICJlZDMyOTBFbnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNiIgKwogICAgICAiNF85MVwwMzBbIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLiIgKwogICAgICAiUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZCIgKwogICAgICAiMzJGaXhlZDY0OTFFbnRyeVwwMjJ3XG5cMDMzZmllbGRfbWFwX3NmaXhlZDMyX2YiICsKICAgICAgImxvYXRfOTJcMDMwXFwgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpIiArCiAgICAgICJ0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpIiArCiAgICAgICJ4ZWQzMkZsb2F0OTJFbnRyeVwwMjJ3XG5cMDMzZmllbGRfbWFwX3NmaXhlZDMyXyIgKwogICAgICAiaW50MzJfOTNcMDMwXSBcMDAzKFwwMTMyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubCIgKwogICAgICAiaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZiIgKwogICAgICAiaXhlZDMySW50MzI5M0VudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfc2ZpeGVkMzIiICsKICAgICAgIl9pbnQ2NF85NFwwMzBeIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFMiICsKICAgICAgImZpeGVkMzJJbnQ2NDk0RW50cnlcMDIye1xuXDAzNWZpZWxkX21hcF9zZml4ZWQzIiArCiAgICAgICIyX21lc3NhZ2VfOTVcMDMwXyBcMDAzKFwwMTMyVC5wcm90b2J1Zi5leHBlcmltZW50IiArCiAgICAgICJhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlcMDIyfVxuXDAzNmZpZWxkX21hcF9zZiIgKwogICAgICAiaXhlZDMyX3NmaXhlZDMyXzk2XDAzMGAgXDAwMyhcMDEzMlUucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLiIgKwogICAgICAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeVwwMjJ9XG5cMDM2ZmllbGQiICsKICAgICAgIl9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTdcMDMwYSBcMDAzKFwwMTMyVS5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5XDAyMnkiICsKICAgICAgIlxuXDAzNGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOThcMDMwYiBcMDAzKFwwMTMyUy5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMIiArCiAgICAgICJpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyIiArCiAgICAgICJ5XDAyMnlcblwwMzRmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5XDAzMGMgXDAwMyhcMDEzMiIgKwogICAgICAiUy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYSIgKwogICAgICAiZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RSIgKwogICAgICAibnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDBcMDMwZCAiICsKICAgICAgIlwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk0iICsKICAgICAgImVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU3RyaW4iICsKICAgICAgImcxMDBFbnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xIiArCiAgICAgICIwMVwwMzBlIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByIiArCiAgICAgICJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyIiArCiAgICAgICJVaW50MzIxMDFFbnRyeVwwMjJ7XG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX3VpbiIgKwogICAgICAidDY0XzEwMlwwMzBmIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saSIgKwogICAgICAidGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaSIsCiAgICAgICJ4ZWQzMlVpbnQ2NDEwMkVudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfc2ZpeGVkNiIgKwogICAgICAiNF9ib29sXzEwM1wwMzBnIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiU2ZpeGVkNjRCb29sMTAzRW50cnlcMDIyeVxuXDAzNGZpZWxkX21hcF9zZml4ZWQiICsKICAgICAgIjY0X2J5dGVzXzEwNFwwMzBoIFwwMDMoXDAxMzJTLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE0iICsKICAgICAgImFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5XDAyMntcblwwMzVmaWVsZF9tYXBfc2ZpIiArCiAgICAgICJ4ZWQ2NF9kb3VibGVfMTA1XDAzMGkgXDAwMyhcMDEzMlQucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUVudHJ5XDAyMndcblwwMzNmaWVsZF9tYSIgKwogICAgICAicF9zZml4ZWQ2NF9lbnVtXzEwNlwwMzBqIFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlcMDIyfVxuXDAzNmZpZWxkX20iICsKICAgICAgImFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3XDAzMGsgXDAwMyhcMDEzMlUucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeVwwMjJ9XG5cMDM2IiArCiAgICAgICJmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDhcMDMwbCBcMDAzKFwwMTMyVS5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMIiArCiAgICAgICJpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVuIiArCiAgICAgICJ0cnlcMDIyeVxuXDAzNGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDlcMDMwbSBcMDAzKCIgKwogICAgICAiXDAxMzJTLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lcyIgKwogICAgICAic2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMCIgKwogICAgICAiOUVudHJ5XDAyMnlcblwwMzRmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwXDAzMG4iICsKICAgICAgIiBcMDAzKFwwMTMyUy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzIiICsKICAgICAgIk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NEludDMiICsKICAgICAgIjIxMTBFbnRyeVwwMjJ5XG5cMDM0ZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExIiArCiAgICAgICIxXDAzMG8gXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRJIiArCiAgICAgICJudDY0MTExRW50cnlcMDIyfVxuXDAzNmZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYSIgKwogICAgICAiZ2VfMTEyXDAzMHAgXDAwMyhcMDEzMlUucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdCIgKwogICAgICAiZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeCIgKwogICAgICAiZWQ2NE1lc3NhZ2UxMTJFbnRyeVwwMjJcMTc3XG5cMDM3ZmllbGRfbWFwX3NmaXhlZDYiICsKICAgICAgIjRfc2ZpeGVkMzJfMTEzXDAzMHEgXDAwMyhcMDEzMlYucHJvdG9idWYuZXhwZXJpbWUiICsKICAgICAgIm50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWwiICsKICAgICAgImRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlcMDIyXDE3N1xuXDAzN2ZpZWxkX21hIiArCiAgICAgICJwX3NmaXhlZDY0X3NmaXhlZDY0XzExNFwwMzByIFwwMDMoXDAxMzJWLnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNEVudHJ5XDAyMntcbiIgKwogICAgICAiXDAzNWZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1XDAzMHMgXDAwMyhcMDEzMlQucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUVudCIgKwogICAgICAicnlcMDIye1xuXDAzNWZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2XDAzMHQgXDAwMygiICsKICAgICAgIlwwMTMyVC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXMiICsKICAgICAgInNhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDEiICsKICAgICAgIjE2RW50cnlcMDIye1xuXDAzNWZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3IiArCiAgICAgICJcMDMwdSBcMDAzKFwwMTMyVC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90IiArCiAgICAgICJvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NFN0IiArCiAgICAgICJyaW5nMTE3RW50cnlcMDIye1xuXDAzNWZpZWxkX21hcF9zZml4ZWQ2NF91aW50MyIgKwogICAgICAiMl8xMThcMDMwdiBcMDAzKFwwMTMyVC5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZSIgKwogICAgICAiLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZSIgKwogICAgICAiZDY0VWludDMyMTE4RW50cnlcMDIye1xuXDAzNWZpZWxkX21hcF9zZml4ZWQ2NF8iICsKICAgICAgInVpbnQ2NF8xMTlcMDMwdyBcMDAzKFwwMTMyVC5wcm90b2J1Zi5leHBlcmltZW50YWwiICsKICAgICAgIi5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIlNmaXhlZDY0VWludDY0MTE5RW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9zaW50IiArCiAgICAgICIzMl9ib29sXzEyMFwwMzB4IFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhIiArCiAgICAgICJsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwU2ludDMyQm9vbDEyMEVudHJ5XDAyMnVcblwwMzJmaWVsZF9tYXBfc2ludDMyXyIgKwogICAgICAiYnl0ZXNfMTIxXDAzMHkgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAibGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwUyIgKwogICAgICAiaW50MzJCeXRlczEyMUVudHJ5XDAyMndcblwwMzNmaWVsZF9tYXBfc2ludDMyX2QiICsKICAgICAgIm91YmxlXzEyMlwwMzB6IFwwMDMoXDAxMzJSLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFMiICsKICAgICAgImludDMyRG91YmxlMTIyRW50cnlcMDIyc1xuXDAzMWZpZWxkX21hcF9zaW50MzJfIiArCiAgICAgICJlbnVtXzEyM1wwMzB7IFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5sIiArCiAgICAgICJpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpIiArCiAgICAgICJudDMyRW51bTEyM0VudHJ5XDAyMnlcblwwMzRmaWVsZF9tYXBfc2ludDMyX2ZpeCIgKwogICAgICAiZWQzMl8xMjRcMDMwfCBcMDAzKFwwMTMyUy5wcm90b2J1Zi5leHBlcmltZW50YWwubCIgKwogICAgICAiaXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaSIgKwogICAgICAibnQzMkZpeGVkMzIxMjRFbnRyeVwwMjJ5XG5cMDM0ZmllbGRfbWFwX3NpbnQzMl8iICsKICAgICAgImZpeGVkNjRfMTI1XDAzMH0gXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBTaW50MzJGaXhlZDY0MTI1RW50cnlcMDIydVxuXDAzMmZpZWxkX21hcF9zaW50IiArCiAgICAgICIzMl9mbG9hdF8xMjZcMDMwfiBcMDAzKFwwMTMyUS5wcm90b2J1Zi5leHBlcmltZW50IiArCiAgICAgICJhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcFNpbnQzMkZsb2F0MTI2RW50cnlcMDIydVxuXDAzMmZpZWxkX21hcF9zaW50MyIgKwogICAgICAiMl9pbnQzMl8xMjdcMDMwXDE3NyBcMDAzKFwwMTMyUS5wcm90b2J1Zi5leHBlcmltZW50YSIgKwogICAgICAibC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYSIgKwogICAgICAicFNpbnQzMkludDMyMTI3RW50cnlcMDIydlxuXDAzMmZpZWxkX21hcF9zaW50MzIiICsKICAgICAgIl9pbnQ2NF8xMjhcMDMwXDIwMFwwMDEgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBTaW50MzJJbnQ2NDEyOEVudHJ5XDAyMnpcblwwMzRmaWVsZF9tYXBfc2ludDMyIiArCiAgICAgICJfbWVzc2FnZV8xMjlcMDMwXDIwMVwwMDEgXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlcMDIyfFxuXDAzNWZpZWxkX21hcF9zaSIgKwogICAgICAibnQzMl9zZml4ZWQzMl8xMzBcMDMwXDIwMlwwMDEgXDAwMyhcMDEzMlQucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLiIgKwogICAgICAiRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudHJ5XDAyMnxcblwwMzVmaWVsZF8iICsKICAgICAgIm1hcF9zaW50MzJfc2ZpeGVkNjRfMTMxXDAzMFwyMDNcMDAxIFwwMDMoXDAxMzJULnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXQiICsKICAgICAgImhNYXBzLkZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeVwwMjJ4XG5cMDMzIiArCiAgICAgICJmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzJcMDMwXDIwNFwwMDEgXDAwMyhcMDEzMlIucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0IiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeVwwMjJ4IiArCiAgICAgICJcblwwMzNmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzNcMDMwXDIwNVwwMDEgXDAwMyhcMDEzMlIucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeSIgKwogICAgICAiXDAyMnhcblwwMzNmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzRcMDMwXDIwNlwwMDEgXDAwMyhcMDEzMlIiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWciICsKICAgICAgImVMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnQiICsKICAgICAgInJ5XDAyMnhcblwwMzNmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzVcMDMwXDIwN1wwMDEgXDAwMyhcMDEzIiArCiAgICAgICIyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzIiArCiAgICAgICJhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJVaW50MzIxMzVFIiArCiAgICAgICJudHJ5XDAyMnhcblwwMzNmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzZcMDMwXDIxMFwwMDEgXDAwMyIgKwogICAgICAiKFwwMTMyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZSIgKwogICAgICAic3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJVaW50NjQxMyIgKwogICAgICAiNkVudHJ5XDAyMnRcblwwMzFmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3XDAzMFwyMTFcMDAxIFwwMDMiICsKICAgICAgIihcMDEzMlAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWUiICsKICAgICAgInNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0Qm9vbDEzN0UiICsKICAgICAgIm50cnlcMDIydlxuXDAzMmZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4XDAzMFwyMTJcMDAxIFwwMDMoIiArCiAgICAgICJcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFIiArCiAgICAgICJudHJ5XDAyMnhcblwwMzNmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzlcMDMwXDIxM1wwMDEgXDAwMyIgKwogICAgICAiKFwwMTMyUi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZSIgKwogICAgICAic3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50NjREb3VibGUxMyIgKwogICAgICAiOUVudHJ5XDAyMnRcblwwMzFmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwXDAzMFwyMTRcMDAxIFwwMDMiICsKICAgICAgIihcMDEzMlAucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWUiICsKICAgICAgInNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0RW51bTE0MEUiICsKICAgICAgIm50cnlcMDIyelxuXDAzNGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDFcMDMwXDIxNVwwMDEgIiArCiAgICAgICJcMDAzKFwwMTMyUy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNIiArCiAgICAgICJlc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRGaXhlZDMyIiArCiAgICAgICIxNDFFbnRyeVwwMjJ6XG5cMDM0ZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiIgKwogICAgICAiXDAzMFwyMTZcMDAxIFwwMDMoXDAxMzJTLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlBybyIgKwogICAgICAidG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEZpeCIgKwogICAgICAiZWQ2NDE0MkVudHJ5XDAyMnZcblwwMzJmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzEiICsKICAgICAgIjQzXDAzMFwyMTdcMDAxIFwwMDMoXDAxMzJRLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlAiICsKICAgICAgInJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEYiICsKICAgICAgImxvYXQxNDNFbnRyeVwwMjJ2XG5cMDMyZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xIiArCiAgICAgICI0NFwwMzBcMjIwXDAwMSBcMDAzKFwwMTMyUS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5QIiArCiAgICAgICJyb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRJIiArCiAgICAgICJudDMyMTQ0RW50cnlcMDIydlxuXDAzMmZpZWxkX21hcF9zaW50NjRfaW50NjRfMSIgKwogICAgICAiNDVcMDMwXDIyMVwwMDEgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUCIgKwogICAgICAicm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0SSIgKwogICAgICAibnQ2NDE0NUVudHJ5XDAyMnpcblwwMzRmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2UiICsKICAgICAgIl8xNDZcMDMwXDIyMlwwMDEgXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUiICsKICAgICAgIi5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDYiICsKICAgICAgIjRNZXNzYWdlMTQ2RW50cnlcMDIyfFxuXDAzNWZpZWxkX21hcF9zaW50NjRfc2ZpIiArCiAgICAgICJ4ZWQzMl8xNDdcMDMwXDIyM1wwMDEgXDAwMyhcMDEzMlQucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwIiArCiAgICAgICJTaW50NjRTZml4ZWQzMjE0N0VudHJ5XDAyMnxcblwwMzVmaWVsZF9tYXBfc2ludCIgKwogICAgICAiNjRfc2ZpeGVkNjRfMTQ4XDAzMFwyMjRcMDAxIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaSIgKwogICAgICAibWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWEiICsKICAgICAgInBfc2ludDY0X3NpbnQzMl8xNDlcMDMwXDIyNVwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeVwwMjJ4XG5cMDMzZmllbGRfIiArCiAgICAgICJtYXBfc2ludDY0X3NpbnQ2NF8xNTBcMDMwXDIyNlwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNIiArCiAgICAgICJhcHMuRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeVwwMjJ4XG5cMDMzZmllbCIgKwogICAgICAiZF9tYXBfc2ludDY0X3N0cmluZ18xNTFcMDMwXDIyN1wwMDEgXDAwMyhcMDEzMlIucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdCIgKwogICAgICAiaE1hcHMuRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeVwwMjJ4XG5cMDMzZmkiICsKICAgICAgImVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTJcMDMwXDIzMFwwMDEgXDAwMyhcMDEzMlIucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeVwwMjJ4XG5cMDMzIiArCiAgICAgICJmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTNcMDMwXDIzMVwwMDEgXDAwMyhcMDEzMlIucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0IiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeVwwMjJ0IiArCiAgICAgICJcblwwMzFmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0XDAzMFwyMzJcMDAxIFwwMDMoXDAxMzJQLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdCIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nQm9vbDE1NEVudHJ5XDAyMnZcblwwMzIiICsKICAgICAgImZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1XDAzMFwyMzNcMDAxIFwwMDMoXDAxMzJRLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeVwwMjJ4XG5cMDMzIiArCiAgICAgICJmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTZcMDMwXDIzNFwwMDEgXDAwMyhcMDEzMlIucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0IiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeVwwMjJ0IiArCiAgICAgICJcblwwMzFmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3XDAzMFwyMzVcMDAxIFwwMDMoXDAxMzJQLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdCIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nRW51bTE1N0VudHJ5XDAyMnpcblwwMzQiICsKICAgICAgImZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNThcMDMwXDIzNlwwMDEgXDAwMyhcMDEzMlMucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGkiICsKICAgICAgInRlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnkiICsKICAgICAgIlwwMjJ6XG5cMDM0ZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OVwwMzBcMjM3XDAwMSBcMDAzKFwwMTMyIiArCiAgICAgICJTLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhIiArCiAgICAgICJnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFIiArCiAgICAgICJudHJ5XDAyMnZcblwwMzJmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MFwwMzBcMjQwXDAwMSBcMDAzKCIgKwogICAgICAiXDAxMzJRLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lcyIgKwogICAgICAic2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRSIgKwogICAgICAibnRyeVwwMjJ2XG5cMDMyZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjFcMDMwXDI0MVwwMDEgXDAwMygiICsKICAgICAgIlwwMTMyUS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXMiICsKICAgICAgInNhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdJbnQzMjE2MUUiICsKICAgICAgIm50cnlcMDIydlxuXDAzMmZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyXDAzMFwyNDJcMDAxIFwwMDMoIiArCiAgICAgICJcMDEzMlEucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nSW50NjQxNjJFIiArCiAgICAgICJudHJ5XDAyMnpcblwwMzRmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzXDAzMFwyNDNcMDAxICIgKwogICAgICAiXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTSIgKwogICAgICAiZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nTWVzc2FnZSIgKwogICAgICAiMTYzRW50cnlcMDIyfFxuXDAzNWZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTYiICsKICAgICAgIjRcMDMwXDI0NFwwMDEgXDAwMyhcMDEzMlQucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHIiICsKICAgICAgIm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nU2YiICsKICAgICAgIml4ZWQzMjE2NEVudHJ5XDAyMnxcblwwMzVmaWVsZF9tYXBfc3RyaW5nX3NmaXhlIiArCiAgICAgICJkNjRfMTY1XDAzMFwyNDVcMDAxIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5sIiArCiAgICAgICJpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFN0IiArCiAgICAgICJyaW5nU2ZpeGVkNjQxNjVFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3N0cmluZyIgKwogICAgICAiX3NpbnQzMl8xNjZcMDMwXDI0NlwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBTdHJpbmdTaW50MzIxNjZFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3N0cmkiICsKICAgICAgIm5nX3NpbnQ2NF8xNjdcMDMwXDI0N1wwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWUiICsKICAgICAgIm50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWwiICsKICAgICAgImRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3N0IiArCiAgICAgICJyaW5nX3N0cmluZ18xNjhcMDMwXDI1MFwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwXyIgKwogICAgICAic3RyaW5nX3VpbnQzMl8xNjlcMDMwXDI1MVwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLiIgKwogICAgICAiRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWEiICsKICAgICAgInBfc3RyaW5nX3VpbnQ2NF8xNzBcMDMwXDI1MlwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeVwwMjJ0XG5cMDMxZmllbGRfIiArCiAgICAgICJtYXBfdWludDMyX2Jvb2xfMTcxXDAzMFwyNTNcMDAxIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5XDAyMnZcblwwMzJmaWVsZF9tYSIgKwogICAgICAicF91aW50MzJfYnl0ZXNfMTcyXDAzMFwyNTRcMDAxIFwwMDMoXDAxMzJRLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWEiICsKICAgICAgInBfdWludDMyX2RvdWJsZV8xNzNcMDMwXDI1NVwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeVwwMjJ0XG5cMDMxZmllbGRfIiArCiAgICAgICJtYXBfdWludDMyX2VudW1fMTc0XDAzMFwyNTZcMDAxIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5XDAyMnpcblwwMzRmaWVsZF9tYSIgKwogICAgICAicF91aW50MzJfZml4ZWQzMl8xNzVcMDMwXDI1N1wwMDEgXDAwMyhcMDEzMlMucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlcMDIyelxuXDAzNGZpZWwiICsKICAgICAgImRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NlwwMzBcMjYwXDAwMSBcMDAzKFwwMTMyUy5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeVwwMjJ2XG5cMDMyIiArCiAgICAgICJmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3N1wwMzBcMjYxXDAwMSBcMDAzKFwwMTMyUS5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlcMDIydlxuXDAzMiIgKwogICAgICAiZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzhcMDMwXDI2MlwwMDEgXDAwMyhcMDEzMlEucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSIgKwogICAgICAiV2l0aE1hcHMuRmllbGRNYXBVaW50MzJJbnQzMjE3OEVudHJ5XDAyMnZcblwwMzIiICsKICAgICAgImZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5XDAzMFwyNjNcMDAxIFwwMDMoXDAxMzJRLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeVwwMjJ6XG5cMDM0IiArCiAgICAgICJmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwXDAzMFwyNjRcMDAxIFwwMDMoXDAxMzJTLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpIiArCiAgICAgICJ0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyTWVzc2FnZTE4MEVudHJ5IiArCiAgICAgICJcMDIyfFxuXDAzNWZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxXDAzMFwyNjVcMDAxIFwwMDMoXDAxMyIgKwogICAgICAiMlQucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzcyIgKwogICAgICAiYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyU2ZpeGVkMzIxOCIgKwogICAgICAiMUVudHJ5XDAyMnxcblwwMzVmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MlwwMzAiICsKICAgICAgIlwyNjZcMDAxIFwwMDMoXDAxMzJULnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3QiICsKICAgICAgIm8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMlNmaXgiICsKICAgICAgImVkNjQxODJFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfIiArCiAgICAgICIxODNcMDMwXDI2N1wwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuIiArCiAgICAgICJQcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyIiArCiAgICAgICJTaW50MzIxODNFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQzMl9zaW50NiIgKwogICAgICAiNF8xODRcMDMwXDI3MFwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdCIgKwogICAgICAiZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludCIgKwogICAgICAiMzJTaW50NjQxODRFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQzMl9zdHIiICsKICAgICAgImluZ18xODVcMDMwXDI3MVwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmwiICsKICAgICAgIml0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWkiICsKICAgICAgIm50MzJTdHJpbmcxODVFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQzMl91IiArCiAgICAgICJpbnQzMl8xODZcMDMwXDI3MlwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwIiArCiAgICAgICJVaW50MzJVaW50MzIxODZFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQzMiIgKwogICAgICAiX3VpbnQ2NF8xODdcMDMwXDI3M1wwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBVaW50MzJVaW50NjQxODdFbnRyeVwwMjJ0XG5cMDMxZmllbGRfbWFwX3VpbnQiICsKICAgICAgIjY0X2Jvb2xfMTg4XDAzMFwyNzRcMDAxIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE0iICsKICAgICAgImFwVWludDY0Qm9vbDE4OEVudHJ5XDAyMnZcblwwMzJmaWVsZF9tYXBfdWludDY0IiArCiAgICAgICJfYnl0ZXNfMTg5XDAzMFwyNzVcMDAxIFwwMDMoXDAxMzJRLnByb3RvYnVmLmV4cGVyaW1lbnRhIiArCiAgICAgICJsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwVWludDY0Qnl0ZXMxODlFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQ2NCIgKwogICAgICAiX2RvdWJsZV8xOTBcMDMwXDI3NlwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBVaW50NjREb3VibGUxOTBFbnRyeVwwMjJ0XG5cMDMxZmllbGRfbWFwX3VpbnQiICsKICAgICAgIjY0X2VudW1fMTkxXDAzMFwyNzdcMDAxIFwwMDMoXDAxMzJQLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE0iICsKICAgICAgImFwVWludDY0RW51bTE5MUVudHJ5XDAyMnpcblwwMzRmaWVsZF9tYXBfdWludDY0IiArCiAgICAgICJfZml4ZWQzMl8xOTJcMDMwXDMwMFwwMDEgXDAwMyhcMDEzMlMucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlcMDIyelxuXDAzNGZpZWxkX21hcF91aSIgKwogICAgICAibnQ2NF9maXhlZDY0XzE5M1wwMzBcMzAxXDAwMSBcMDAzKFwwMTMyUy5wcm90b2J1Zi5leHBlciIgKwogICAgICAiaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeVwwMjJ2XG5cMDMyZmllbGRfbWEiICsKICAgICAgInBfdWludDY0X2Zsb2F0XzE5NFwwMzBcMzAyXDAwMSBcMDAzKFwwMTMyUS5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHMiICsKICAgICAgIi5GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlcMDIydlxuXDAzMmZpZWxkX21hIiArCiAgICAgICJwX3VpbnQ2NF9pbnQzMl8xOTVcMDMwXDMwM1wwMDEgXDAwMyhcMDEzMlEucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzIiArCiAgICAgICIuRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5XDAyMnZcblwwMzJmaWVsZF9tYSIgKwogICAgICAicF91aW50NjRfaW50NjRfMTk2XDAzMFwzMDRcMDAxIFwwMDMoXDAxMzJRLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeVwwMjJ6XG5cMDM0ZmllbGRfbWEiICsKICAgICAgInBfdWludDY0X21lc3NhZ2VfMTk3XDAzMFwzMDVcMDAxIFwwMDMoXDAxMzJTLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5XDAyMnxcblwwMzVmaWVsIiArCiAgICAgICJkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4XDAzMFwzMDZcMDAxIFwwMDMoXDAxMzJULnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXIiArCiAgICAgICJpdGhNYXBzLkZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeVwwMjJ8IiArCiAgICAgICJcblwwMzVmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OVwwMzBcMzA3XDAwMSBcMDAzKFwwMTMyVCIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZyIgKwogICAgICAiZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RSIgKwogICAgICAibnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwXDAzMFwzMTBcMDAxIFwwMDMiICsKICAgICAgIihcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWUiICsKICAgICAgInNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0U2ludDMyMjAiICsKICAgICAgIjBFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxXDAzMFwzMTFcMDAxIiArCiAgICAgICIgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yIiArCiAgICAgICJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0U2ludDY0IiArCiAgICAgICIyMDFFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyXDAzMCIgKwogICAgICAiXDMxMlwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdCIgKwogICAgICAibzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0U3RyaSIgKwogICAgICAibmcyMDJFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAiICsKICAgICAgIjNcMDMwXDMxM1wwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHIiICsKICAgICAgIm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0VWkiICsKICAgICAgIm50MzIyMDNFbnRyeVwwMjJ4XG5cMDMzZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfIiArCiAgICAgICIyMDRcMDMwXDMxNFwwMDEgXDAwMyhcMDEzMlIucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuIiArCiAgICAgICJQcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0IiArCiAgICAgICJVaW50NjQyMDRFbnRyeVwwMzI4XG5cMDI2RmllbGRNYXBCb29sQm9vbDFFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWwiICsKICAgICAgImRNYXBCb29sQnl0ZXMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMjpcblwwMzBGaWVsZE1hcEJvb2xEb3VibGUzRW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMnBcblwwMjZGaWVsZCIgKwogICAgICAiTWFwQm9vbEVudW00RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJFXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvIiArCiAgICAgICIyTWVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvbyIgKwogICAgICAibEZpeGVkMzI1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMDc6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI5XG5cMDI3RmllbGRNYXBCIiArCiAgICAgICJvb2xGbG9hdDdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAwMjpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI5XG5cMDI3RmllbGRNYXBCb28iICsKICAgICAgImxJbnQ2NDlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDMiICsKICAgICAgIjpcMDAyOFwwMDFcMDMya1xuXDAzMkZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXDAxMFwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyLS5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllIiArCiAgICAgICJsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEJvb2xTZml4ZWQ2NCIgKwogICAgICAiMTJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMiIgKwogICAgICAiO1xuXDAzMUZpZWxkTWFwQm9vbFNpbnQzMjEzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xTaW50IiArCiAgICAgICI2NDE0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4IiArCiAgICAgICJcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwQm9vbFVpIiArCiAgICAgICJudDMyMTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOiIgKwogICAgICAiXDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBGaXhlIiArCiAgICAgICJkMzJCb29sMThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWEiICsKICAgICAgInBGaXhlZDMyRG91YmxlMjBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMydFxuXDAzMkZpZWxkTWFwRml4ZWQzMkVudW0yMUVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJFXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyNi5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlQiICsKICAgICAgImVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNSIgKwogICAgICAiRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEiICsKICAgICAgIihcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkMzIiICsKICAgICAgIkZsb2F0MjRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDIiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRiIgKwogICAgICAiaXhlZDMySW50NjQyNkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJuXG5cMDM1RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMjxcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzItLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGU6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwIiArCiAgICAgICJGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDMyU2ludDMyMyIgKwogICAgICAiMEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPiIgKwogICAgICAiXG5cMDM0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRml4ZWQzIiArCiAgICAgICIyU3RyaW5nMzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXHQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTSIgKwogICAgICAiYXBGaXhlZDMyVWludDY0MzRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwRml4ZWQ2NEJvb2wzNUUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzIiArCiAgICAgICJGaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNiIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkNjREbyIgKwogICAgICAidWJsZTM3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOiIgKwogICAgICAiXDAwMjhcMDAxXDAzMnRcblwwMzJGaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFwwMDZcMDIyRVxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjYucHJvdG9idWYuZXhwZXJpbSIgKwogICAgICAiZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZS5UZXN0RW51bTpcMDAyOCIgKwogICAgICAiXDAwMVwwMzI/XG5cMDM1RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcEZpIiArCiAgICAgICJ4ZWQ2NEZpeGVkNjQ0MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmkiICsKICAgICAgImVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcciIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkNjRJbnQ2IiArCiAgICAgICI0NDNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyblxuXDAzNUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAwNlwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyLS5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbCIgKwogICAgICAiZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcEZpeGVkNjRTZmkiICsKICAgICAgInhlZDY0NDZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjAiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcCIgKwogICAgICAiRml4ZWQ2NFNpbnQ2NDQ4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNCIgKwogICAgICAiRmllbGRNYXBGaXhlZDY0VWludDMyNTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkNjRVIiArCiAgICAgICJpbnQ2NDUxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0IiwKICAgICAgIjpcMDAyOFwwMDFcMDMyOlxuXDAzMEZpZWxkTWFwSW50MzJCb29sNTJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50MyIgKwogICAgICAiMkJ5dGVzNTNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKCIgKwogICAgICAiXDAxNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJyXG5cMDMwRmllbGRNYXBJIiArCiAgICAgICJudDMyRW51bTU1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJFXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk0iICsKICAgICAgImVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludDMyIiArCiAgICAgICJGaXhlZDMyNTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAwNzpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWEiICsKICAgICAgInBJbnQzMkZsb2F0NThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZCIgKwogICAgICAiTWFwSW50MzJJbnQ2NDYwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmxcblwwMzNGaWVsZE1hcEludDMyTWVzc2FnZTYxRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjxcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzItLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGU6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEluIiArCiAgICAgICJ0MzJTZml4ZWQ2NDYzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWwiICsKICAgICAgImRNYXBJbnQzMlNpbnQ2NDY1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDMyU3RyaW5nNjZFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMjxcblwwMzIiICsKICAgICAgIkZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyIiArCiAgICAgICJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJVaW50NiIgKwogICAgICAiNDY4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMSIgKwogICAgICAiXDAzMjpcblwwMzBGaWVsZE1hcEludDY0Qm9vbDY5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTA6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDY0Qnl0IiArCiAgICAgICJlczcwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4IiArCiAgICAgICJcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyclxuXDAzMEZpZWxkTWFwSW50NjQiICsKICAgICAgIkVudW03MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyRVxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MiIgKwogICAgICAiNi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYSIgKwogICAgICAiZ2VMaXRlLlRlc3RFbnVtOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBJbnQ2NEZpeGUiICsKICAgICAgImQzMjczRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludCIgKwogICAgICAiNjRGbG9hdDc1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMDI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDY0SW50MzI3NkVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJIiArCiAgICAgICJudDY0SW50NjQ3N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJsXG5cMDMzRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEVudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyLS5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzI+IiArCiAgICAgICJcblwwMzRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBJbnQ2NFMiICsKICAgICAgImZpeGVkNjQ4MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDIwOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcCIgKwogICAgICAiSW50NjRTaW50NjQ4MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbCIgKwogICAgICAiZE1hcEludDY0VWludDMyODRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDY0VWludDY0ODVFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPVxuXDAzMyIgKwogICAgICAiRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTciICsKICAgICAgIlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZWQzMkIiICsKICAgICAgInl0ZXM4N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDoiICsKICAgICAgIlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMnVcblwwMzNGaWVsZE1hcCIgKwogICAgICAiU2ZpeGVkMzJFbnVtODlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMkVcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE2MjYucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlTGl0ZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwUyIgKwogICAgICAiZml4ZWQzMkZpeGVkMzI5MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQiICsKICAgICAgIjkxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzIiICsKICAgICAgIj5cblwwMzRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZSIgKwogICAgICAiZDMySW50MzI5M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyb1xuXDAzNkZpZWxkIiArCiAgICAgICJNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyPCIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyLS5wcm90b2J1Zi5leHBlcmltZW50YWwubGkiICsKICAgICAgInRlLlByb3RvMk1lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzJBXG5cMDM3RmllbGRNYXBTZml4IiArCiAgICAgICJlZDMyU2ZpeGVkMzI5NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJBXG5cMDM3RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OSIgKwogICAgICAiN0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyPyIgKwogICAgICAiXG5cMDM1RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlIiArCiAgICAgICJkMzJTaW50NjQ5OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpIiArCiAgICAgICJlbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkMzIiICsKICAgICAgIlVpbnQ2NDEwMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDA0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTSIgKwogICAgICAiYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNSIgKwogICAgICAidmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0RG91YmwiICsKICAgICAgImUxMDVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjgiICsKICAgICAgIlwwMDFcMDMydlxuXDAzNEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDIwXDAyMkVcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW0iICsKICAgICAgImVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjgiICsKICAgICAgIlwwMDFcMDMyQVxuXDAzN0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMkFcblwwMzdGaWVsZE1hcCIgKwogICAgICAiU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNSIgKwogICAgICAidmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDY0RmxvYXQiICsKICAgICAgIjEwOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI/XG5cMDM1RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaSIgKwogICAgICAieGVkNjRJbnQ2NDExMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJwXG5cMDM3RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIiICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMi0ucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzJCXG4gRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMkJcbiBGaWVsIiArCiAgICAgICJkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQ2NCIgKwogICAgICAiU2ludDMyMTE1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMjE6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsIiArCiAgICAgICJkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0VWkiICsKICAgICAgIm50MzIxMThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDQ6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE0iICsKICAgICAgImFwU2ludDMyQm9vbDEyMEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTaW50MzJCeXRlczEyMUVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RiIgKwogICAgICAiaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjEiICsKICAgICAgIlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJ0XG5cMDMyRmllbGRNYXBTaW50MzJFbnUiICsKICAgICAgIm0xMjNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMkVcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI2LiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZSIgKwogICAgICAiTGl0ZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU2ludDMyRml4ZWQiICsKICAgICAgIjMyMTI0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwUyIgKwogICAgICAiaW50MzJGbG9hdDEyNkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTaW50MzJJbnQzMjEyN0VudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllIiArCiAgICAgICJsZE1hcFNpbnQzMkludDY0MTI4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMm5cblwwMzVGaWVsZE1hcFNpbnQzMk1lc3NhZyIgKwogICAgICAiZTEyOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMi0uIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlIiArCiAgICAgICJMaXRlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmkiICsKICAgICAgImVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlNpIiArCiAgICAgICJudDMyMTMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlNpbnQzMlN0cmluZzEzNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDMyVWludDMyMTM1RSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0IiArCiAgICAgICJGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBTaW50NjRCbyIgKwogICAgICAib2wxMzdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTA6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2luIiArCiAgICAgICJ0NjREb3VibGUxMzlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMydFxuXDAzMkZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJFXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyNi5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFIiArCiAgICAgICJudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWwiICsKICAgICAgImRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcciIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQ2NEZsb2F0IiArCiAgICAgICIxNDNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDYiICsKICAgICAgIjRJbnQ2NDE0NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDAzOlwwMDI4XDAwMVwwMzJuXG5cMDM1RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMjxcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzItLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGU6XDAwMjhcMDAxXDAzMkAiICsKICAgICAgIlxuXDAzNkZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ludCIgKwogICAgICAiNjRTZml4ZWQ2NDE0OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpIiArCiAgICAgICJlbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDY0U3RyaSIgKwogICAgICAibmcxNTFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2kiICsKICAgICAgIm50NjRVaW50NjQxNTNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwU3RyaW5nQm9vbDE1NEVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWwiICsKICAgICAgImRNYXBTdHJpbmdCeXRlczE1NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1IiArCiAgICAgICJ2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU3RyaW5nRG91YmxlMSIgKwogICAgICAiNTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzIiICsKICAgICAgInRcblwwMzJGaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFx0XDAyMkVcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhIiArCiAgICAgICJsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cbiIgKwogICAgICAiXDAzNUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU3RyaW5nIiArCiAgICAgICJGaXhlZDY0MTU5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTSIgKwogICAgICAiYXBTdHJpbmdJbnQzMjE2MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMm5cblwwMzUiICsKICAgICAgIkZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxIiArCiAgICAgICIoXHRcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMi0ucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwIiArCiAgICAgICJTdHJpbmdTZml4ZWQzMjE2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQiICsKICAgICAgIjE2NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyPlxuXDAzNEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTdHJpIiArCiAgICAgICJuZ1NpbnQ2NDE2N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWwiICsKICAgICAgImRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTdHJpbmdVaW50NjQiICsKICAgICAgIjE3MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDQ6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyPFxuXDAzMkZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMyIiArCiAgICAgICJCeXRlczE3MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKCIgKwogICAgICAiXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJ0XG5cMDMyRmllbGRNYSIgKwogICAgICAicFVpbnQzMkVudW0xNzRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJFXG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlBybyIgKwogICAgICAidG8yTWVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFUiICsKICAgICAgImludDMyRml4ZWQzMjE3NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NiIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuIiArCiAgICAgICJcMDMzRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMySW4iICsKICAgICAgInQzMjE3OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMm5cblwwMzVGaWVsZE1hcFVpIiArCiAgICAgICJudDMyTWVzc2FnZTE4MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMjxcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDEzMi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlTGl0ZTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwVWludDMyU2ZpeCIgKwogICAgICAiZWQzMjE4MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTciICsKICAgICAgIjpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE0iICsKICAgICAgImFwVWludDMyU2ludDMyMTgzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50MzJTaW50NjQxOCIgKwogICAgICAiNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMj4iICsKICAgICAgIlxuXDAzNEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxICIgKwogICAgICAiXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyIiArCiAgICAgICJVaW50MzIxODZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDQ6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE0iICsKICAgICAgImFwVWludDY0Qm9vbDE4OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50NjRCeXRlczE4OUVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RiIgKwogICAgICAiaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDQiICsKICAgICAgIlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJ0XG5cMDMyRmllbGRNYXBVaW50NjRFbnUiICsKICAgICAgIm0xOTFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMkVcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI2LiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZSIgKwogICAgICAiTGl0ZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwVWludDY0Rml4ZWQiICsKICAgICAgIjMyMTkyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVSIgKwogICAgICAiaW50NjRGbG9hdDE5NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllIiArCiAgICAgICJsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMm5cblwwMzVGaWVsZE1hcFVpbnQ2NE1lc3NhZyIgKwogICAgICAiZTE5N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMi0uIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlIiArCiAgICAgICJMaXRlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmkiICsKICAgICAgImVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQ2NFNpIiArCiAgICAgICJudDMyMjAwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlVpbnQ2NFN0cmluZzIwMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDY0VWludDMyMjAzRSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0IiArCiAgICAgICJGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMTpTXG5cMDE2ZmllbGRfZG91YmxlXzFcMDIyOyIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZyIgKwogICAgICAiZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDAxIFwwMDEoXDAwMTpSXG5ccmZpZWxkX2Zsb2F0IiArCiAgICAgICJfMlwwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lIiArCiAgICAgICJzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDAyIFwwMDEoXDAwMjpSXG5ccmZpZWxkX2kiICsKICAgICAgIm50NjRfM1wwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3QiICsKICAgICAgIm8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDAzIFwwMDEoXDAwMzpTXG5cMDE2ZmllIiArCiAgICAgICJsZF91aW50NjRfNFwwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlIiArCiAgICAgICIuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDA0IFwwMDEoXDAwNDpSIiArCiAgICAgICJcblxyZmllbGRfaW50MzJfNVwwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDA1IFwwMDEiICsKICAgICAgIihcMDA1OlRcblwwMTdmaWVsZF9maXhlZDY0XzZcMDIyOy5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvIiArCiAgICAgICJuc1wwMzBcMDA2IFwwMDEoXDAwNjpUXG5cMDE3ZmllbGRfZml4ZWQzMl83XDAyMjsucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeCIgKwogICAgICAidGVuc2lvbnNcMDMwXDAwNyBcMDAxKFwwMDc6UVxuXDAxNGZpZWxkX2Jvb2xfOFwwMjI7LnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXQiICsKICAgICAgImhFeHRlbnNpb25zXDAzMFwwMTAgXDAwMShcMDEwOlNcblwwMTZmaWVsZF9zdHJpbmdfOVwwMjI7LnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpIiArCiAgICAgICJ0ZVdpdGhFeHRlbnNpb25zXDAzMFx0IFwwMDEoXHQ6XDIwNFwwMDFcblwwMjBmaWVsZF9tZXNzYWdlIiArCiAgICAgICJfMTBcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNIiArCiAgICAgICJlc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwXG4gXDAwMShcMDEzMi0ucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZTpTXG4iICsKICAgICAgIlwwMTZmaWVsZF9ieXRlc18xMVwwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDEzIFwwMDEiICsKICAgICAgIihcMDE0OlRcblwwMTdmaWVsZF91aW50MzJfMTJcMDIyOy5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvIiArCiAgICAgICJuc1wwMzBcMDE0IFwwMDEoXHI6XDIxMlwwMDFcblxyZmllbGRfZW51bV8xM1wwMjI7LnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0IiArCiAgICAgICJlbnNpb25zXDAzMFxyIFwwMDEoXDAxNjI2LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saSIgKwogICAgICAidGUuUHJvdG8yTWVzc2FnZUxpdGUuVGVzdEVudW06VlxuXDAyMWZpZWxkX3MiICsKICAgICAgImZpeGVkMzJfMTRcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS4iICsKICAgICAgIlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwXDAxNiBcMDAxKFwwMTc6VlxuIiArCiAgICAgICJcMDIxZmllbGRfc2ZpeGVkNjRfMTVcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50IiArCiAgICAgICJhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwIiArCiAgICAgICJcMDE3IFwwMDEoXDAyMDpUXG5cMDE3ZmllbGRfc2ludDMyXzE2XDAyMjsucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbiIgKwogICAgICAic2lvbnNcMDMwXDAyMCBcMDAxKFwwMjE6VFxuXDAxN2ZpZWxkX3NpbnQ2NF8xN1wwMjI7LnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXQiICsKICAgICAgImhFeHRlbnNpb25zXDAzMFwwMjEgXDAwMShcMDIyOl1cblwwMjRmaWVsZF9kb3VibGVfbGlzdF8xIiArCiAgICAgICI4XDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMFwwMjIgXDAwMyhcMDAxQlwwMDJcMDIwXDAwMDpcXFxuXDAyM2ZpZWwiICsKICAgICAgImRfZmxvYXRfbGlzdF8xOVwwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgImxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDIzIFwwMDMiICsKICAgICAgIihcMDAyQlwwMDJcMDIwXDAwMDpcXFxuXDAyM2ZpZWxkX2ludDY0X2xpc3RfMjBcMDIyOy5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aCIgKwogICAgICAiRXh0ZW5zaW9uc1wwMzBcMDI0IFwwMDMoXDAwM0JcMDAyXDAyMFwwMDA6XVxuXDAyNGZpZWxkX3VpbnQ2NF9saXMiICsKICAgICAgInRfMjFcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzIiICsKICAgICAgIk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwXDAyNSBcMDAzKFwwMDRCXDAwMlwwMjBcMDAwOlxcXG5cMDIzZiIgKwogICAgICAiaWVsZF9pbnQzMl9saXN0XzIyXDAyMjsucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMCIgKwogICAgICAiXDAyNiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAwOl5cblwwMjVmaWVsZF9maXhlZDY0X2xpc3RfMjNcMDIyOy5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXQiICsKICAgICAgImVXaXRoRXh0ZW5zaW9uc1wwMzBcMDI3IFwwMDMoXDAwNkJcMDAyXDAyMFwwMDA6XlxuXDAyNWZpZWxkX2ZpeGVkIiArCiAgICAgICIzMl9saXN0XzI0XDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuIiArCiAgICAgICJQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMFwwMzAgXDAwMyhcMDA3QlwwMDJcMDIwIiArCiAgICAgICJcMDAwOltcblwwMjJmaWVsZF9ib29sX2xpc3RfMjVcMDIyOy5wcm90b2J1Zi5leHBlciIgKwogICAgICAiaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVucyIgKwogICAgICAiaW9uc1wwMzBcMDMxIFwwMDMoXDAxMEJcMDAyXDAyMFwwMDA6XVxuXDAyNGZpZWxkX3N0cmluZ19saXN0XzI2XDAyMjsiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWciICsKICAgICAgImVMaXRlV2l0aEV4dGVuc2lvbnNcMDMwXDAzMiBcMDAzKFx0QlwwMDJcMDIwXDAwMDpcMjE1XDAwMVxuXDAyNWZpZWxkXyIgKwogICAgICAibWVzc2FnZV9saXN0XzI3XDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAibGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMFwwMzMgXDAwMyIgKwogICAgICAiKFwwMTMyLS5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZSIgKwogICAgICAic3NhZ2VMaXRlQlwwMDJcMDIwXDAwMDpcXFxuXDAyM2ZpZWxkX2J5dGVzX2xpc3RfMjhcMDIyOy5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMIiArCiAgICAgICJpdGVXaXRoRXh0ZW5zaW9uc1wwMzBcMDM0IFwwMDMoXDAxNEJcMDAyXDAyMFwwMDA6XVxuXDAyNGZpZWxkX3VpbiIgKwogICAgICAidDMyX2xpc3RfMjlcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZSIgKwogICAgICAiLlByb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwXDAzNSBcMDAzKFxyQlwwMDIiICsKICAgICAgIlwwMjBcMDAwOlwyMjNcMDAxXG5cMDIyZmllbGRfZW51bV9saXN0XzMwXDAyMjsucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlIiArCiAgICAgICJuc2lvbnNcMDMwXDAzNiBcMDAzKFwwMTYyNi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0IiArCiAgICAgICJlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3RFbnVtQlwwMDJcMDIwXDAwMDpfXG5cMDI2ZmllbCIgKwogICAgICAiZF9zZml4ZWQzMl9saXN0XzMxXDAyMjsucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMCIgKwogICAgICAiXDAzNyBcMDAzKFwwMTdCXDAwMlwwMjBcMDAwOl9cblwwMjZmaWVsZF9zZml4ZWQ2NF9saXN0XzMyXDAyMjsucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGkiICsKICAgICAgInRlV2l0aEV4dGVuc2lvbnNcMDMwICBcMDAzKFwwMjBCXDAwMlwwMjBcMDAwOl1cblwwMjRmaWVsZF9zaW50IiArCiAgICAgICIzMl9saXN0XzMzXDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuIiArCiAgICAgICJQcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMCEgXDAwMyhcMDIxQlwwMDJcMDIwIiArCiAgICAgICJcMDAwOl1cblwwMjRmaWVsZF9zaW50NjRfbGlzdF8zNFwwMjI7LnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZSIgKwogICAgICAibnNpb25zXDAzMFwiIFwwMDMoXDAyMkJcMDAyXDAyMFwwMDA6ZFxuXDAzM2ZpZWxkX2RvdWJsZV9saXN0X3BhIiArCiAgICAgICJja2VkXzM1XDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvIiArCiAgICAgICJ0bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMCMgXDAwMyhcMDAxQlwwMDJcMDIwXDAwMTpjIiArCiAgICAgICJcblwwMzJmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNlwwMjI7LnByb3RvYnVmLiIgKwogICAgICAiZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRSIgKwogICAgICAieHRlbnNpb25zXDAzMCQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMTpjXG5cMDMyZmllbGRfaW50NjRfbGlzdF8iICsKICAgICAgInBhY2tlZF8zN1wwMjI7LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5saXRlLlAiICsKICAgICAgInJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc1wwMzAlIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDEiICsKICAgICAgIjpkXG5cMDMzZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4XDAyMjsucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpIiArCiAgICAgICJ0aEV4dGVuc2lvbnNcMDMwJiBcMDAzKFwwMDRCXDAwMlwwMjBcMDAxOmNcblwwMzJmaWVsZF9pbnQzMl9saSIgKwogICAgICAic3RfcGFja2VkXzM5XDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdCIgKwogICAgICAiZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMFwnIFwwMDMoXDAwNUIiICsKICAgICAgIlwwMDJcMDIwXDAwMTplXG5cMDM0ZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MFwwMjI7LnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpIiArCiAgICAgICJ0ZVdpdGhFeHRlbnNpb25zXDAzMCggXDAwMyhcMDA2QlwwMDJcMDIwXDAwMTplXG5cMDM0ZmllbGRfZml4ZSIgKwogICAgICAiZDMyX2xpc3RfcGFja2VkXzQxXDAyMjsucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwubGl0ZS5Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMCIgKwogICAgICAiKSBcMDAzKFwwMDdCXDAwMlwwMjBcMDAxOmJcblwwMzFmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyXDAyMjsiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWciICsKICAgICAgImVMaXRlV2l0aEV4dGVuc2lvbnNcMDMwKiBcMDAzKFwwMTBCXDAwMlwwMjBcMDAxOmRcblwwMzNmaWVsZF91IiArCiAgICAgICJpbnQzMl9saXN0X3BhY2tlZF80M1wwMjI7LnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uIiArCiAgICAgICJzXDAzMCsgXDAwMyhcckJcMDAyXDAyMFwwMDE6XDIzMlwwMDFcblwwMzFmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQiICsKICAgICAgIjRcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXMiICsKICAgICAgInNhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwLCBcMDAzKFwwMTYyNi5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5saXRlLlByb3RvMk1lc3NhZ2VMaXRlLlRlc3QiICsKICAgICAgIkVudW1CXDAwMlwwMjBcMDAxOmZcblwwMzVmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80IiArCiAgICAgICI1XDAyMjsucHJvdG9idWYuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzIiArCiAgICAgICJzYWdlTGl0ZVdpdGhFeHRlbnNpb25zXDAzMC0gXDAwMyhcMDE3QlwwMDJcMDIwXDAwMTpmXG5cMDM1ZmllbCIgKwogICAgICAiZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NlwwMjI7LnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZSIgKwogICAgICAibnNpb25zXDAzMC4gXDAwMyhcMDIwQlwwMDJcMDIwXDAwMTpkXG5cMDMzZmllbGRfc2ludDMyX2xpc3RfcGEiICsKICAgICAgImNrZWRfNDdcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm8iICsKICAgICAgInRvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwLyBcMDAzKFwwMjFCXDAwMlwwMjBcMDAxOmQiICsKICAgICAgIlxuXDAzM2ZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OFwwMjI7LnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLmxpdGUuUHJvdG8yTWVzc2FnZUxpdGVXaXRoIiArCiAgICAgICJFeHRlbnNpb25zXDAzMDAgXDAwMyhcMDIyQlwwMDJcMDIwXDAwMTp7XG5cMDE0ZmllbGRncm91cDQ5XDAyMjsucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90bzJNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aEV4dGVuc2lvbnNcMDMwMSBcMDAxKFxuMigucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwubGl0ZS5GaWVsZEdyb3VwNDk6XDIwM1wwMDFcblwwMjBmaWVsZGdyb3VwIiArCiAgICAgICJsaXN0NTFcMDIyOy5wcm90b2J1Zi5leHBlcmltZW50YWwubGl0ZS5Qcm90IiArCiAgICAgICJvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNcMDMwMyBcMDAzKFxuMiwucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwubGl0ZS5GaWVsZEdyb3VwTGlzdDUxQiIgKwogICAgICAiMFxuXDAzM2NvbS5nb29nbGUucHJvdG9idWYudGVzdGluZ0JcMDIxUHJvdG8yVGUiICsKICAgICAgInN0aW5nTGl0ZSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZERvdWJsZTEiLCAiRmllbGRGbG9hdDIiLCAiRmllbGRJbnQ2NDMiLCAiRmllbGRVaW50NjQ0IiwgIkZpZWxkSW50MzI1IiwgIkZpZWxkRml4ZWQ2NDYiLCAiRmllbGRGaXhlZDMyNyIsICJGaWVsZEJvb2w4IiwgIkZpZWxkU3RyaW5nOSIsICJGaWVsZE1lc3NhZ2UxMCIsICJGaWVsZEJ5dGVzMTEiLCAiRmllbGRVaW50MzIxMiIsICJGaWVsZEVudW0xMyIsICJGaWVsZFNmaXhlZDMyMTQiLCAiRmllbGRTZml4ZWQ2NDE1IiwgIkZpZWxkU2ludDMyMTYiLCAiRmllbGRTaW50NjQxNyIsICJGaWVsZERvdWJsZUxpc3QxOCIsICJGaWVsZEZsb2F0TGlzdDE5IiwgIkZpZWxkSW50NjRMaXN0MjAiLCAiRmllbGRVaW50NjRMaXN0MjEiLCAiRmllbGRJbnQzMkxpc3QyMiIsICJGaWVsZEZpeGVkNjRMaXN0MjMiLCAiRmllbGRGaXhlZDMyTGlzdDI0IiwgIkZpZWxkQm9vbExpc3QyNSIsICJGaWVsZFN0cmluZ0xpc3QyNiIsICJGaWVsZE1lc3NhZ2VMaXN0MjciLCAiRmllbGRCeXRlc0xpc3QyOCIsICJGaWVsZFVpbnQzMkxpc3QyOSIsICJGaWVsZEVudW1MaXN0MzAiLCAiRmllbGRTZml4ZWQzMkxpc3QzMSIsICJGaWVsZFNmaXhlZDY0TGlzdDMyIiwgIkZpZWxkU2ludDMyTGlzdDMzIiwgIkZpZWxkU2ludDY0TGlzdDM0IiwgIkZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IiwgIkZpZWxkRmxvYXRMaXN0UGFja2VkMzYiLCAiRmllbGRJbnQ2NExpc3RQYWNrZWQzNyIsICJGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCIsICJGaWVsZEludDMyTGlzdFBhY2tlZDM5IiwgIkZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCIsICJGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEiLCAiRmllbGRCb29sTGlzdFBhY2tlZDQyIiwgIkZpZWxkVWludDMyTGlzdFBhY2tlZDQzIiwgIkZpZWxkRW51bUxpc3RQYWNrZWQ0NCIsICJGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1IiwgIkZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYiLCAiRmllbGRTaW50MzJMaXN0UGFja2VkNDciLCAiRmllbGRTaW50NjRMaXN0UGFja2VkNDgiLCAiRmllbGRHcm91cDQ5IiwgIkZpZWxkR3JvdXBMaXN0NTEiLCAiRmllbGREb3VibGU1MyIsICJGaWVsZEZsb2F0NTQiLCAiRmllbGRJbnQ2NDU1IiwgIkZpZWxkVWludDY0NTYiLCAiRmllbGRJbnQzMjU3IiwgIkZpZWxkRml4ZWQ2NDU4IiwgIkZpZWxkRml4ZWQzMjU5IiwgIkZpZWxkQm9vbDYwIiwgIkZpZWxkU3RyaW5nNjEiLCAiRmllbGRNZXNzYWdlNjIiLCAiRmllbGRCeXRlczYzIiwgIkZpZWxkVWludDMyNjQiLCAiRmllbGRTZml4ZWQzMjY1IiwgIkZpZWxkU2ZpeGVkNjQ2NiIsICJGaWVsZFNpbnQzMjY3IiwgIkZpZWxkU2ludDY0NjgiLCAiRmllbGRHcm91cDY5IiwgIkZpZWxkUmVxdWlyZWREb3VibGU3MSIsICJGaWVsZFJlcXVpcmVkRmxvYXQ3MiIsICJGaWVsZFJlcXVpcmVkSW50NjQ3MyIsICJGaWVsZFJlcXVpcmVkVWludDY0NzQiLCAiRmllbGRSZXF1aXJlZEludDMyNzUiLCAiRmllbGRSZXF1aXJlZEZpeGVkNjQ3NiIsICJGaWVsZFJlcXVpcmVkRml4ZWQzMjc3IiwgIkZpZWxkUmVxdWlyZWRCb29sNzgiLCAiRmllbGRSZXF1aXJlZFN0cmluZzc5IiwgIkZpZWxkUmVxdWlyZWRNZXNzYWdlODAiLCAiRmllbGRSZXF1aXJlZEJ5dGVzODEiLCAiRmllbGRSZXF1aXJlZFVpbnQzMjgyIiwgIkZpZWxkUmVxdWlyZWRFbnVtODMiLCAiRmllbGRSZXF1aXJlZFNmaXhlZDMyODQiLCAiRmllbGRSZXF1aXJlZFNmaXhlZDY0ODUiLCAiRmllbGRSZXF1aXJlZFNpbnQzMjg2IiwgIkZpZWxkUmVxdWlyZWRTaW50NjQ4NyIsICJGaWVsZFJlcXVpcmVkR3JvdXA4OCIsICJUZXN0T25lb2YiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXA0OV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZpZWxkSW50MzI1MCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkR3JvdXBMaXN0NTFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGRJbnQzMjUyIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDY5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9GaWVsZEdyb3VwNjlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRHcm91cDY5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZEludDMyNzAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX1JlcXVpcmVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9SZXF1aXJlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVfRmllbGRSZXF1aXJlZEdyb3VwODhfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkUmVxdWlyZWRHcm91cDg4X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlX0ZpZWxkUmVxdWlyZWRHcm91cDg4X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZEludDMyODkiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJFbXB0eUxpdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yRW1wdHlMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMkVtcHR5TGl0ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhFeHRlbnNpb25zX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoRXh0ZW5zaW9uc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwNDlfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfRmllbGRHcm91cDQ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX0ZpZWxkR3JvdXA0OV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGRJbnQzMjUwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfRmllbGRHcm91cExpc3Q1MV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9GaWVsZEdyb3VwTGlzdDUxX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX0ZpZWxkR3JvdXBMaXN0NTFfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZpZWxkSW50MzI1MiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZE1hcEJvb2xCb29sMSIsICJGaWVsZE1hcEJvb2xCeXRlczIiLCAiRmllbGRNYXBCb29sRG91YmxlMyIsICJGaWVsZE1hcEJvb2xFbnVtNCIsICJGaWVsZE1hcEJvb2xGaXhlZDMyNSIsICJGaWVsZE1hcEJvb2xGaXhlZDY0NiIsICJGaWVsZE1hcEJvb2xGbG9hdDciLCAiRmllbGRNYXBCb29sSW50MzI4IiwgIkZpZWxkTWFwQm9vbEludDY0OSIsICJGaWVsZE1hcEJvb2xNZXNzYWdlMTAiLCAiRmllbGRNYXBCb29sU2ZpeGVkMzIxMSIsICJGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyIiwgIkZpZWxkTWFwQm9vbFNpbnQzMjEzIiwgIkZpZWxkTWFwQm9vbFNpbnQ2NDE0IiwgIkZpZWxkTWFwQm9vbFN0cmluZzE1IiwgIkZpZWxkTWFwQm9vbFVpbnQzMjE2IiwgIkZpZWxkTWFwQm9vbFVpbnQ2NDE3IiwgIkZpZWxkTWFwRml4ZWQzMkJvb2wxOCIsICJGaWVsZE1hcEZpeGVkMzJCeXRlczE5IiwgIkZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwIiwgIkZpZWxkTWFwRml4ZWQzMkVudW0yMSIsICJGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIiLCAiRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzIiwgIkZpZWxkTWFwRml4ZWQzMkZsb2F0MjQiLCAiRmllbGRNYXBGaXhlZDMySW50MzIyNSIsICJGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2IiwgIkZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNyIsICJGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4IiwgIkZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkiLCAiRmllbGRNYXBGaXhlZDMyU2ludDMyMzAiLCAiRmllbGRNYXBGaXhlZDMyU2ludDY0MzEiLCAiRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIiLCAiRmllbGRNYXBGaXhlZDMyVWludDMyMzMiLCAiRmllbGRNYXBGaXhlZDMyVWludDY0MzQiLCAiRmllbGRNYXBGaXhlZDY0Qm9vbDM1IiwgIkZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYiLCAiRmllbGRNYXBGaXhlZDY0RG91YmxlMzciLCAiRmllbGRNYXBGaXhlZDY0RW51bTM4IiwgIkZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSIsICJGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAiLCAiRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSIsICJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyIiwgIkZpZWxkTWFwRml4ZWQ2NEludDY0NDMiLCAiRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0IiwgIkZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUiLCAiRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NiIsICJGaWVsZE1hcEZpeGVkNjRTaW50MzI0NyIsICJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCIsICJGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSIsICJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCIsICJGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSIsICJGaWVsZE1hcEludDMyQm9vbDUyIiwgIkZpZWxkTWFwSW50MzJCeXRlczUzIiwgIkZpZWxkTWFwSW50MzJEb3VibGU1NCIsICJGaWVsZE1hcEludDMyRW51bTU1IiwgIkZpZWxkTWFwSW50MzJGaXhlZDMyNTYiLCAiRmllbGRNYXBJbnQzMkZpeGVkNjQ1NyIsICJGaWVsZE1hcEludDMyRmxvYXQ1OCIsICJGaWVsZE1hcEludDMySW50MzI1OSIsICJGaWVsZE1hcEludDMySW50NjQ2MCIsICJGaWVsZE1hcEludDMyTWVzc2FnZTYxIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQzMjYyIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzIiwgIkZpZWxkTWFwSW50MzJTaW50MzI2NCIsICJGaWVsZE1hcEludDMyU2ludDY0NjUiLCAiRmllbGRNYXBJbnQzMlN0cmluZzY2IiwgIkZpZWxkTWFwSW50MzJVaW50MzI2NyIsICJGaWVsZE1hcEludDMyVWludDY0NjgiLCAiRmllbGRNYXBJbnQ2NEJvb2w2OSIsICJGaWVsZE1hcEludDY0Qnl0ZXM3MCIsICJGaWVsZE1hcEludDY0RG91YmxlNzEiLCAiRmllbGRNYXBJbnQ2NEVudW03MiIsICJGaWVsZE1hcEludDY0Rml4ZWQzMjczIiwgIkZpZWxkTWFwSW50NjRGaXhlZDY0NzQiLCAiRmllbGRNYXBJbnQ2NEZsb2F0NzUiLCAiRmllbGRNYXBJbnQ2NEludDMyNzYiLCAiRmllbGRNYXBJbnQ2NEludDY0NzciLCAiRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCIsICJGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSIsICJGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCIsICJGaWVsZE1hcEludDY0U2ludDMyODEiLCAiRmllbGRNYXBJbnQ2NFNpbnQ2NDgyIiwgIkZpZWxkTWFwSW50NjRTdHJpbmc4MyIsICJGaWVsZE1hcEludDY0VWludDMyODQiLCAiRmllbGRNYXBJbnQ2NFVpbnQ2NDg1IiwgIkZpZWxkTWFwU2ZpeGVkMzJCb29sODYiLCAiRmllbGRNYXBTZml4ZWQzMkJ5dGVzODciLCAiRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4IiwgIkZpZWxkTWFwU2ZpeGVkMzJFbnVtODkiLCAiRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCIsICJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxIiwgIkZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0IiwgIkZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTciLCAiRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4IiwgIkZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSIsICJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwIiwgIkZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEiLCAiRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMiIsICJGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMyIsICJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQiLCAiRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSIsICJGaWVsZE1hcFNmaXhlZDY0RW51bTEwNiIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNyIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCIsICJGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkiLCAiRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwIiwgIkZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSIsICJGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMiIsICJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMiLCAiRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0IiwgIkZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUiLCAiRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNiIsICJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3IiwgIkZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgiLCAiRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSIsICJGaWVsZE1hcFNpbnQzMkJvb2wxMjAiLCAiRmllbGRNYXBTaW50MzJCeXRlczEyMSIsICJGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMiIsICJGaWVsZE1hcFNpbnQzMkVudW0xMjMiLCAiRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0IiwgIkZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSIsICJGaWVsZE1hcFNpbnQzMkZsb2F0MTI2IiwgIkZpZWxkTWFwU2ludDMySW50MzIxMjciLCAiRmllbGRNYXBTaW50MzJJbnQ2NDEyOCIsICJGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkiLCAiRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCIsICJGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxIiwgIkZpZWxkTWFwU2ludDMyU2ludDMyMTMyIiwgIkZpZWxkTWFwU2ludDMyU2ludDY0MTMzIiwgIkZpZWxkTWFwU2ludDMyU3RyaW5nMTM0IiwgIkZpZWxkTWFwU2ludDMyVWludDMyMTM1IiwgIkZpZWxkTWFwU2ludDMyVWludDY0MTM2IiwgIkZpZWxkTWFwU2ludDY0Qm9vbDEzNyIsICJGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4IiwgIkZpZWxkTWFwU2ludDY0RG91YmxlMTM5IiwgIkZpZWxkTWFwU2ludDY0RW51bTE0MCIsICJGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEiLCAiRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyIiwgIkZpZWxkTWFwU2ludDY0RmxvYXQxNDMiLCAiRmllbGRNYXBTaW50NjRJbnQzMjE0NCIsICJGaWVsZE1hcFNpbnQ2NEludDY0MTQ1IiwgIkZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NiIsICJGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3IiwgIkZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgiLCAiRmllbGRNYXBTaW50NjRTaW50MzIxNDkiLCAiRmllbGRNYXBTaW50NjRTaW50NjQxNTAiLCAiRmllbGRNYXBTaW50NjRTdHJpbmcxNTEiLCAiRmllbGRNYXBTaW50NjRVaW50MzIxNTIiLCAiRmllbGRNYXBTaW50NjRVaW50NjQxNTMiLCAiRmllbGRNYXBTdHJpbmdCb29sMTU0IiwgIkZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUiLCAiRmllbGRNYXBTdHJpbmdEb3VibGUxNTYiLCAiRmllbGRNYXBTdHJpbmdFbnVtMTU3IiwgIkZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCIsICJGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkiLCAiRmllbGRNYXBTdHJpbmdGbG9hdDE2MCIsICJGaWVsZE1hcFN0cmluZ0ludDMyMTYxIiwgIkZpZWxkTWFwU3RyaW5nSW50NjQxNjIiLCAiRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzIiwgIkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQiLCAiRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSIsICJGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NiIsICJGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NyIsICJGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCIsICJGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSIsICJGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCIsICJGaWVsZE1hcFVpbnQzMkJvb2wxNzEiLCAiRmllbGRNYXBVaW50MzJCeXRlczE3MiIsICJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MyIsICJGaWVsZE1hcFVpbnQzMkVudW0xNzQiLCAiRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1IiwgIkZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NiIsICJGaWVsZE1hcFVpbnQzMkZsb2F0MTc3IiwgIkZpZWxkTWFwVWludDMySW50MzIxNzgiLCAiRmllbGRNYXBVaW50MzJJbnQ2NDE3OSIsICJGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAiLCAiRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSIsICJGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyIiwgIkZpZWxkTWFwVWludDMyU2ludDMyMTgzIiwgIkZpZWxkTWFwVWludDMyU2ludDY0MTg0IiwgIkZpZWxkTWFwVWludDMyU3RyaW5nMTg1IiwgIkZpZWxkTWFwVWludDMyVWludDMyMTg2IiwgIkZpZWxkTWFwVWludDMyVWludDY0MTg3IiwgIkZpZWxkTWFwVWludDY0Qm9vbDE4OCIsICJGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5IiwgIkZpZWxkTWFwVWludDY0RG91YmxlMTkwIiwgIkZpZWxkTWFwVWludDY0RW51bTE5MSIsICJGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIiLCAiRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzIiwgIkZpZWxkTWFwVWludDY0RmxvYXQxOTQiLCAiRmllbGRNYXBVaW50NjRJbnQzMjE5NSIsICJGaWVsZE1hcFVpbnQ2NEludDY0MTk2IiwgIkZpZWxkTWFwVWludDY0TWVzc2FnZTE5NyIsICJGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4IiwgIkZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkiLCAiRmllbGRNYXBVaW50NjRTaW50MzIyMDAiLCAiRmllbGRNYXBVaW50NjRTaW50NjQyMDEiLCAiRmllbGRNYXBVaW50NjRTdHJpbmcyMDIiLCAiRmllbGRNYXBVaW50NjRVaW50MzIyMDMiLCAiRmllbGRNYXBVaW50NjRVaW50NjQyMDQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sQm9vbDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sQnl0ZXMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEVudW00RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50MzI4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDMyMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDMyMzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDM4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50NjQ0M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDY0NTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQzMjU2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDY1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTA0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDExMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCb29sMTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTMwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTM3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTY0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTcxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTg4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTkzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfbGl0ZV9Qcm90bzJNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX2xpdGVfUHJvdG8yTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9saXRlX1Byb3RvMk1lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBmaWVsZERvdWJsZTEuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBmaWVsZEZsb2F0Mi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEpKTsKICAgIGZpZWxkSW50NjQzLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMikpOwogICAgZmllbGRVaW50NjQ0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMykpOwogICAgZmllbGRJbnQzMjUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0KSk7CiAgICBmaWVsZEZpeGVkNjQ2LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNSkpOwogICAgZmllbGRGaXhlZDMyNy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDYpKTsKICAgIGZpZWxkQm9vbDguaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3KSk7CiAgICBmaWVsZFN0cmluZzkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg4KSk7CiAgICBmaWVsZE1lc3NhZ2UxMC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDkpKTsKICAgIGZpZWxkQnl0ZXMxMS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEwKSk7CiAgICBmaWVsZFVpbnQzMjEyLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTEpKTsKICAgIGZpZWxkRW51bTEzLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTIpKTsKICAgIGZpZWxkU2ZpeGVkMzIxNC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEzKSk7CiAgICBmaWVsZFNmaXhlZDY0MTUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxNCkpOwogICAgZmllbGRTaW50MzIxNi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE1KSk7CiAgICBmaWVsZFNpbnQ2NDE3LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTYpKTsKICAgIGZpZWxkRG91YmxlTGlzdDE4LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTcpKTsKICAgIGZpZWxkRmxvYXRMaXN0MTkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxOCkpOwogICAgZmllbGRJbnQ2NExpc3QyMC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE5KSk7CiAgICBmaWVsZFVpbnQ2NExpc3QyMS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDIwKSk7CiAgICBmaWVsZEludDMyTGlzdDIyLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjEpKTsKICAgIGZpZWxkRml4ZWQ2NExpc3QyMy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDIyKSk7CiAgICBmaWVsZEZpeGVkMzJMaXN0MjQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyMykpOwogICAgZmllbGRCb29sTGlzdDI1LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjQpKTsKICAgIGZpZWxkU3RyaW5nTGlzdDI2LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjUpKTsKICAgIGZpZWxkTWVzc2FnZUxpc3QyNy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI2KSk7CiAgICBmaWVsZEJ5dGVzTGlzdDI4LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjcpKTsKICAgIGZpZWxkVWludDMyTGlzdDI5LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjgpKTsKICAgIGZpZWxkRW51bUxpc3QzMC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI5KSk7CiAgICBmaWVsZFNmaXhlZDMyTGlzdDMxLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzApKTsKICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzIuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMSkpOwogICAgZmllbGRTaW50MzJMaXN0MzMuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMikpOwogICAgZmllbGRTaW50NjRMaXN0MzQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMykpOwogICAgZmllbGREb3VibGVMaXN0UGFja2VkMzUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzNCkpOwogICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDM1KSk7CiAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzYpKTsKICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzcpKTsKICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzOCkpOwogICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzkpKTsKICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQwKSk7CiAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDIuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0MSkpOwogICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0MikpOwogICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDMpKTsKICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0NCkpOwogICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ1KSk7CiAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ2KSk7CiAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ3KSk7CiAgICBmaWVsZEdyb3VwNDkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0OCkpOwogICAgZmllbGRHcm91cExpc3Q1MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ5KSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQD5b9Xz03cvANN3LwAuAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL1Byb3RvM1Rlc3RpbmcuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9wcm90bzNfbWVzc2FnZS5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nOwoKcHVibGljIGZpbmFsIGNsYXNzIFByb3RvM1Rlc3RpbmcgewogIHByaXZhdGUgUHJvdG8zVGVzdGluZygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBQcm90bzNTcGVjaWFsRmllbGROYW1lT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNTcGVjaWFsRmllbGROYW1lKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIHJlZ3VsYXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVndWxhck5hbWUuCiAgICAgKi8KICAgIGRvdWJsZSBnZXRSZWd1bGFyTmFtZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgY2FjaGVkX3NpemUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNhY2hlZFNpemUuCiAgICAgKi8KICAgIGludCBnZXRDYWNoZWRTaXplXygpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgc2VyaWFsaXplZF9zaXplID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkU2l6ZS4KICAgICAqLwogICAgbG9uZyBnZXRTZXJpYWxpemVkU2l6ZV8oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2xhc3MuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGNsYXNzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRDbGFzc19CeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvM1NwZWNpYWxGaWVsZE5hbWUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUpCiAgICAgIFByb3RvM1NwZWNpYWxGaWVsZE5hbWVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvM1NwZWNpYWxGaWVsZE5hbWUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUHJvdG8zU3BlY2lhbEZpZWxkTmFtZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvM1NwZWNpYWxGaWVsZE5hbWUoKSB7CiAgICAgIGNsYXNzX18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBQcm90bzNTcGVjaWFsRmllbGROYW1lKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNTcGVjaWFsRmllbGROYW1lX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNTcGVjaWFsRmllbGROYW1lX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRUdVTEFSX05BTUVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgZG91YmxlIHJlZ3VsYXJOYW1lXyA9IDBEOwogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgcmVndWxhcl9uYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZWd1bGFyTmFtZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRSZWd1bGFyTmFtZSgpIHsKICAgICAgcmV0dXJuIHJlZ3VsYXJOYW1lXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQUNIRURfU0laRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgY2FjaGVkU2l6ZV9fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgY2FjaGVkX3NpemUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNhY2hlZFNpemUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q2FjaGVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiBjYWNoZWRTaXplX187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VSSUFMSVpFRF9TSVpFX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGxvbmcgc2VyaWFsaXplZFNpemVfXyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBzZXJpYWxpemVkX3NpemUgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNlcmlhbGl6ZWRTaXplLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRTZXJpYWxpemVkU2l6ZV8oKSB7CiAgICAgIHJldHVybiBzZXJpYWxpemVkU2l6ZV9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBjbGFzc19fID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2xhc3MuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENsYXNzXygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjbGFzc19fOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgY2xhc3NfXyA9IHM7CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgY2xhc3MuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRDbGFzc19CeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjbGFzc19fOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBjbGFzc19fID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKHJlZ3VsYXJOYW1lXykgIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxLCByZWd1bGFyTmFtZV8pOwogICAgICB9CiAgICAgIGlmIChjYWNoZWRTaXplX18gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGNhY2hlZFNpemVfXyk7CiAgICAgIH0KICAgICAgaWYgKHNlcmlhbGl6ZWRTaXplX18gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgzLCBzZXJpYWxpemVkU2l6ZV9fKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkoY2xhc3NfXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDQsIGNsYXNzX18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKHJlZ3VsYXJOYW1lXykgIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDEsIHJlZ3VsYXJOYW1lXyk7CiAgICAgIH0KICAgICAgaWYgKGNhY2hlZFNpemVfXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBjYWNoZWRTaXplX18pOwogICAgICB9CiAgICAgIGlmIChzZXJpYWxpemVkU2l6ZV9fICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgzLCBzZXJpYWxpemVkU2l6ZV9fKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkoY2xhc3NfXykpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDQsIGNsYXNzX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSkgb2JqOwoKICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRSZWd1bGFyTmFtZSgpKQogICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgIG90aGVyLmdldFJlZ3VsYXJOYW1lKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRDYWNoZWRTaXplXygpCiAgICAgICAgICAhPSBvdGhlci5nZXRDYWNoZWRTaXplXygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRTZXJpYWxpemVkU2l6ZV8oKQogICAgICAgICAgIT0gb3RoZXIuZ2V0U2VyaWFsaXplZFNpemVfKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRDbGFzc18oKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRDbGFzc18oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRUdVTEFSX05BTUVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldFJlZ3VsYXJOYW1lKCkpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0FDSEVEX1NJWkVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRDYWNoZWRTaXplXygpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTRVJJQUxJWkVEX1NJWkVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0U2VyaWFsaXplZFNpemVfKCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENsYXNzXygpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM1NwZWNpYWxGaWVsZE5hbWV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zU3BlY2lhbEZpZWxkTmFtZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM1NwZWNpYWxGaWVsZE5hbWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlZ3VsYXJOYW1lXyA9IDBEOwogICAgICAgIGNhY2hlZFNpemVfXyA9IDA7CiAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IDBMOwogICAgICAgIGNsYXNzX18gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNTcGVjaWFsRmllbGROYW1lX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVndWxhck5hbWVfID0gcmVndWxhck5hbWVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNhY2hlZFNpemVfXyA9IGNhY2hlZFNpemVfXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zZXJpYWxpemVkU2l6ZV9fID0gc2VyaWFsaXplZFNpemVfXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jbGFzc19fID0gY2xhc3NfXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldFJlZ3VsYXJOYW1lKCkgIT0gMEQpIHsKICAgICAgICAgIHNldFJlZ3VsYXJOYW1lKG90aGVyLmdldFJlZ3VsYXJOYW1lKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0Q2FjaGVkU2l6ZV8oKSAhPSAwKSB7CiAgICAgICAgICBzZXRDYWNoZWRTaXplXyhvdGhlci5nZXRDYWNoZWRTaXplXygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldFNlcmlhbGl6ZWRTaXplXygpICE9IDBMKSB7CiAgICAgICAgICBzZXRTZXJpYWxpemVkU2l6ZV8ob3RoZXIuZ2V0U2VyaWFsaXplZFNpemVfKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmdldENsYXNzXygpLmlzRW1wdHkoKSkgewogICAgICAgICAgY2xhc3NfXyA9IG90aGVyLmNsYXNzX187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA5OiB7CiAgICAgICAgICAgICAgICByZWd1bGFyTmFtZV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOQogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGNhY2hlZFNpemVfXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY2xhc3NfXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgZG91YmxlIHJlZ3VsYXJOYW1lXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgcmVndWxhcl9uYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlZ3VsYXJOYW1lLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldFJlZ3VsYXJOYW1lKCkgewogICAgICAgIHJldHVybiByZWd1bGFyTmFtZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSByZWd1bGFyX25hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZWd1bGFyTmFtZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlZ3VsYXJOYW1lKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICByZWd1bGFyTmFtZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSByZWd1bGFyX25hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZWd1bGFyTmFtZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgcmVndWxhck5hbWVfID0gMEQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGNhY2hlZFNpemVfXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBjYWNoZWRfc2l6ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjYWNoZWRTaXplLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldENhY2hlZFNpemVfKCkgewogICAgICAgIHJldHVybiBjYWNoZWRTaXplX187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGNhY2hlZF9zaXplID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY2FjaGVkU2l6ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENhY2hlZFNpemVfKGludCB2YWx1ZSkgewoKICAgICAgICBjYWNoZWRTaXplX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGNhY2hlZF9zaXplID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2FjaGVkU2l6ZV8oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGNhY2hlZFNpemVfXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBzZXJpYWxpemVkU2l6ZV9fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkU2l6ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0U2VyaWFsaXplZFNpemVfKCkgewogICAgICAgIHJldHVybiBzZXJpYWxpemVkU2l6ZV9fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBzZXJpYWxpemVkX3NpemUgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzZXJpYWxpemVkU2l6ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNlcmlhbGl6ZWRTaXplXyhsb25nIHZhbHVlKSB7CgogICAgICAgIHNlcmlhbGl6ZWRTaXplX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IHNlcmlhbGl6ZWRfc2l6ZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNlcmlhbGl6ZWRTaXplXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgc2VyaWFsaXplZFNpemVfXyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgY2xhc3NfXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNsYXNzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q2xhc3NfKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gY2xhc3NfXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGNsYXNzX18gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjbGFzcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldENsYXNzX0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gY2xhc3NfXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgY2xhc3NfXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNsYXNzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2xhc3NfXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2xhc3NfKCkgewogICAgICAgIGNsYXNzX18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRDbGFzc18oKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBjbGFzcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENsYXNzX0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGNsYXNzX18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM1NwZWNpYWxGaWVsZE5hbWUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNTcGVjaWFsRmllbGROYW1lKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNTcGVjaWFsRmllbGROYW1lIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zU3BlY2lhbEZpZWxkTmFtZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzNTcGVjaWFsRmllbGROYW1lPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM1NwZWNpYWxGaWVsZE5hbWU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zU3BlY2lhbEZpZWxkTmFtZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zU3BlY2lhbEZpZWxkTmFtZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFByb3RvM01lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlMS4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkRG91YmxlMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDIuCiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkRmxvYXQyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0My4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDQuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjQ0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNS4KICAgICAqLwogICAgaW50IGdldEZpZWxkSW50MzI1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0Ni4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjQ2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNy4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMjcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w4LgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkQm9vbDgoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmc5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlMTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRNZXNzYWdlMTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNZXNzYWdlMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlMTBPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlczExLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzIxMi4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyMTIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW0xMy4KICAgICAqLwogICAgaW50IGdldEZpZWxkRW51bTEzVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW0xMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZEVudW0xMygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyMTQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyMTQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDE1LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ZpeGVkNjQxNSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyMTYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMjE2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNpbnQ2NDE3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRG91YmxlTGlzdDE4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdDE4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdDE4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZsb2F0TGlzdDE5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdDE5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3QyMC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDY0TGlzdDIwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdDIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdDIxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQ2NExpc3QyMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3QyMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDMyTGlzdDIyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0MjMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0MjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRCb29sTGlzdDI1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdDI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0MjUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZ0xpc3QyNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZ0xpc3QyNkJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IAogICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWVzc2FnZUxpc3QyNyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRCeXRlc0xpc3QyOExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCeXRlc0xpc3QyOC4KICAgICAqLwogICAgaW50IGdldEZpZWxkQnl0ZXNMaXN0MjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXNMaXN0MjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlc0xpc3QyOChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQzMkxpc3QyOS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0MjkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjkoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gZ2V0RmllbGRFbnVtTGlzdDMwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEVudW1MaXN0MzAuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEVudW1MaXN0MzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZEVudW1MaXN0MzBWYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEVudW1MaXN0MzBWYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkMzJMaXN0MzEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzEoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzJMaXN0MzMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50NjRMaXN0MzQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDY0TGlzdDM0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdDM0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNpbnQ2NExpc3QzNChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0UGFja2VkMzUuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzNyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3RQYWNrZWQzOS4KICAgICAqLwogICAgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAqLwogICAgaW50IGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDQoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NS4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50MzJMaXN0UGFja2VkNDcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGREb3VibGU1MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGbG9hdDU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZEZsb2F0NTQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkSW50NjQ1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0NTUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDY0NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NTYuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQzMjU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjU3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjU3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQ2NDU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ1OC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjQ1OCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRGaXhlZDMyNTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNTkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzI1OSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRCb29sNjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sNjAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU3RyaW5nNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nNjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTYyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWVzc2FnZTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTYyT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMjY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDMyNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyNjUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDY0NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkNjQ2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQ2Ni4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0NjYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ludDMyNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMjY3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNpbnQ2NDY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ludDY0NjgoKTsKCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RPbmVvZkNhc2UgZ2V0VGVzdE9uZW9mQ2FzZSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvM01lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UpCiAgICAgIFByb3RvM01lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvM01lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUHJvdG8zTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvM01lc3NhZ2UoKSB7CiAgICAgIGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgICAgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgZmllbGRFbnVtMTNfID0gMDsKICAgICAgZmllbGREb3VibGVMaXN0MThfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvM01lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFRlc3RFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgWkVSTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk9ORSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgT05FKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+VFdPID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBUV08oMiksCiAgICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5aRVJPID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBaRVJPX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk9ORSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRXTyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFdPX1ZBTFVFID0gMjsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBaRVJPOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gT05FOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gVFdPOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBUZXN0RW51bT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgVGVzdEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFRlc3RFbnVtLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIGRlc2NyaXB0b3Igb2YgYW4gdW5yZWNvZ25pemVkIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgVGVzdEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSkKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgdGVzdE9uZW9mXzsKICAgIHB1YmxpYyBlbnVtIFRlc3RPbmVvZkNhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgRklFTERfRE9VQkxFXzUzKDUzKSwKICAgICAgRklFTERfRkxPQVRfNTQoNTQpLAogICAgICBGSUVMRF9JTlQ2NF81NSg1NSksCiAgICAgIEZJRUxEX1VJTlQ2NF81Nig1NiksCiAgICAgIEZJRUxEX0lOVDMyXzU3KDU3KSwKICAgICAgRklFTERfRklYRUQ2NF81OCg1OCksCiAgICAgIEZJRUxEX0ZJWEVEMzJfNTkoNTkpLAogICAgICBGSUVMRF9CT09MXzYwKDYwKSwKICAgICAgRklFTERfU1RSSU5HXzYxKDYxKSwKICAgICAgRklFTERfTUVTU0FHRV82Mig2MiksCiAgICAgIEZJRUxEX0JZVEVTXzYzKDYzKSwKICAgICAgRklFTERfVUlOVDMyXzY0KDY0KSwKICAgICAgRklFTERfU0ZJWEVEMzJfNjUoNjUpLAogICAgICBGSUVMRF9TRklYRUQ2NF82Nig2NiksCiAgICAgIEZJRUxEX1NJTlQzMl82Nyg2NyksCiAgICAgIEZJRUxEX1NJTlQ2NF82OCg2OCksCiAgICAgIFRFU1RPTkVPRl9OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBUZXN0T25lb2ZDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdE9uZW9mQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIFRlc3RPbmVvZkNhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgNTM6IHJldHVybiBGSUVMRF9ET1VCTEVfNTM7CiAgICAgICAgICBjYXNlIDU0OiByZXR1cm4gRklFTERfRkxPQVRfNTQ7CiAgICAgICAgICBjYXNlIDU1OiByZXR1cm4gRklFTERfSU5UNjRfNTU7CiAgICAgICAgICBjYXNlIDU2OiByZXR1cm4gRklFTERfVUlOVDY0XzU2OwogICAgICAgICAgY2FzZSA1NzogcmV0dXJuIEZJRUxEX0lOVDMyXzU3OwogICAgICAgICAgY2FzZSA1ODogcmV0dXJuIEZJRUxEX0ZJWEVENjRfNTg7CiAgICAgICAgICBjYXNlIDU5OiByZXR1cm4gRklFTERfRklYRUQzMl81OTsKICAgICAgICAgIGNhc2UgNjA6IHJldHVybiBGSUVMRF9CT09MXzYwOwogICAgICAgICAgY2FzZSA2MTogcmV0dXJuIEZJRUxEX1NUUklOR182MTsKICAgICAgICAgIGNhc2UgNjI6IHJldHVybiBGSUVMRF9NRVNTQUdFXzYyOwogICAgICAgICAgY2FzZSA2MzogcmV0dXJuIEZJRUxEX0JZVEVTXzYzOwogICAgICAgICAgY2FzZSA2NDogcmV0dXJuIEZJRUxEX1VJTlQzMl82NDsKICAgICAgICAgIGNhc2UgNjU6IHJldHVybiBGSUVMRF9TRklYRUQzMl82NTsKICAgICAgICAgIGNhc2UgNjY6IHJldHVybiBGSUVMRF9TRklYRUQ2NF82NjsKICAgICAgICAgIGNhc2UgNjc6IHJldHVybiBGSUVMRF9TSU5UMzJfNjc7CiAgICAgICAgICBjYXNlIDY4OiByZXR1cm4gRklFTERfU0lOVDY0XzY4OwogICAgICAgICAgY2FzZSAwOiByZXR1cm4gVEVTVE9ORU9GX05PVF9TRVQ7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIFRlc3RPbmVvZkNhc2UKICAgIGdldFRlc3RPbmVvZkNhc2UoKSB7CiAgICAgIHJldHVybiBUZXN0T25lb2ZDYXNlLmZvck51bWJlcigKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9ET1VCTEVfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBkb3VibGUgZmllbGREb3VibGUxXyA9IDBEOwogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTEoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZTFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgZmxvYXQgZmllbGRGbG9hdDJfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDIoKSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0Ml87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfM19GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBsb25nIGZpZWxkSW50NjQzXyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDMoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0XzRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQ0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NDQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NDRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyXzVfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1KCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMjVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBsb25nIGZpZWxkRml4ZWQ2NDZfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjQ2KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0Nl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl83X0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGludCBmaWVsZEZpeGVkMzI3XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMjcoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzI3XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MXzhfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgYm9vbGVhbiBmaWVsZEJvb2w4XyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sOCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbDhfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NUUklOR185X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBmaWVsZFN0cmluZzlfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmc5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGRTdHJpbmc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGZpZWxkU3RyaW5nOV8gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGZpZWxkU3RyaW5nOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFXzEwX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGZpZWxkTWVzc2FnZTEwXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2UxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZE1lc3NhZ2UxMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxME9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkTWVzc2FnZTEwXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU18xMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGZpZWxkQnl0ZXMxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlczExLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXMxMSgpIHsKICAgICAgcmV0dXJuIGZpZWxkQnl0ZXMxMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDMyXzEyX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgcHJpdmF0ZSBpbnQgZmllbGRVaW50MzIxMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzIxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMjEyKCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzIxMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRU5VTV8xM19GSUVMRF9OVU1CRVIgPSAxMzsKICAgIHByaXZhdGUgaW50IGZpZWxkRW51bTEzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW0xMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldEZpZWxkRW51bTEzVmFsdWUoKSB7CiAgICAgIHJldHVybiBmaWVsZEVudW0xM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtMTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtMTMoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5mb3JOdW1iZXIoZmllbGRFbnVtMTNfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSID0gMTQ7CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMjE0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMjE0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF8xNV9GSUVMRF9OVU1CRVIgPSAxNTsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFNmaXhlZDY0MTVfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgaW50IGZpZWxkU2ludDMyMTZfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyMTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzIxNigpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyMTZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF8xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0MTdfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3QxOF8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGREb3VibGVMaXN0MThDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3QxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0MTgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF9MSVNUXzE5X0ZJRUxEX05VTUJFUiA9IDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IGZpZWxkRmxvYXRMaXN0MTlfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0MTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF9MSVNUXzIwX0ZJRUxEX05VTUJFUiA9IDIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3QyMF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3QyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3QyMENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0MjAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfMjFfRklFTERfTlVNQkVSID0gMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFVpbnQ2NExpc3QyMV8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQ2NExpc3QyMUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0TGlzdDIxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfTElTVF8yMl9GSUVMRF9OVU1CRVIgPSAyMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRJbnQzMkxpc3QyMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdDIyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3QyMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0MjJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF9MSVNUXzIzX0ZJRUxEX05VTUJFUiA9IDIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRGaXhlZDY0TGlzdDIzXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdDIzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdDIzXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyX0xJU1RfMjRfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkRml4ZWQzMkxpc3QyNF8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0MjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF9MSVNUXzI1X0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdDI1XyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3QyNV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0MjUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdDI1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdDI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1Xy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TVFJJTkdfTElTVF8yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFN0cmluZ0xpc3QyNi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFX0xJU1RfMjdfRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNZXNzYWdlTGlzdDI3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU19MSVNUXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRCeXRlc0xpc3QyOF8gPQogICAgICAgIGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXNMaXN0MjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXNMaXN0MjgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9MSVNUXzI5X0ZJRUxEX05VTUJFUiA9IDI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFVpbnQzMkxpc3QyOV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0MjkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRU5VTV9MSVNUXzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0MzBfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gZ2V0RmllbGRFbnVtTGlzdDMwTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+KGZpZWxkRW51bUxpc3QzMF8sIGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3QzMENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRFbnVtTGlzdDMwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8uY29udmVydChmaWVsZEVudW1MaXN0MzBfLmdldChpbmRleCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkRW51bUxpc3QzMFZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3QzMFZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyX0xJU1RfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkMzJMaXN0MzEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0X0xJU1RfMzJfRklFTERfTlVNQkVSID0gMzI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UMzJfTElTVF8zM19GSUVMRF9OVU1CRVIgPSAzMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0MzNfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdDMzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzMyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF9MSVNUXzM0X0ZJRUxEX05VTUJFUiA9IDM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTaW50NjRMaXN0MzRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50NjRMaXN0MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0MzQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdDM0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3QzNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdDM0KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUX1BBQ0tFRF8zNV9GSUVMRF9OVU1CRVIgPSAzNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmdldERvdWJsZShpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF9MSVNUX1BBQ0tFRF8zNl9GSUVMRF9OVU1CRVIgPSAzNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9CiAgICAgICAgZW1wdHlGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5nZXRGbG9hdChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0X0xJU1RfUEFDS0VEXzM3X0ZJRUxEX05VTUJFUiA9IDM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEludDY0TGlzdFBhY2tlZDM3TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQ2NF9MSVNUX1BBQ0tFRF8zOF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyX0xJU1RfUEFDS0VEXzM5X0ZJRUxEX05VTUJFUiA9IDM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzJMaXN0UGFja2VkMzlNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF9MSVNUX1BBQ0tFRF80MF9GSUVMRF9OVU1CRVIgPSA0MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl9MSVNUX1BBQ0tFRF80MV9GSUVMRF9OVU1CRVIgPSA0MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MX0xJU1RfUEFDS0VEXzQyX0ZJRUxEX05VTUJFUiA9IDQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0UGFja2VkNDIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkQm9vbExpc3RQYWNrZWQ0Mk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfTElTVF9QQUNLRURfNDNfRklFTERfTlVNQkVSID0gNDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0VOVU1fTElTVF9QQUNLRURfNDRfRklFTERfTlVNQkVSID0gNDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdFBhY2tlZDQ0XywgZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXy5jb252ZXJ0KGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0VmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0VmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZEVudW1MaXN0UGFja2VkNDRNZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyX0xJU1RfUEFDS0VEXzQ1X0ZJRUxEX05VTUJFUiA9IDQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfTElTVF9QQUNLRURfNDZfRklFTERfTlVNQkVSID0gNDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDMyX0xJU1RfUEFDS0VEXzQ3X0ZJRUxEX05VTUJFUiA9IDQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0UGFja2VkNDdfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N01lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UNjRfTElTVF9QQUNLRURfNDhfRklFTERfTlVNQkVSID0gNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9ET1VCTEVfNTNfRklFTERfTlVNQkVSID0gNTM7CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlNTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZERvdWJsZTUzKCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlNTMoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkRvdWJsZSkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfNTRfRklFTERfTlVNQkVSID0gNTQ7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZsb2F0NTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZsb2F0NTQoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0NTQoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwRjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF81NV9GSUVMRF9OVU1CRVIgPSA1NTsKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50NjQ1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQ1NSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDU1KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UNjRfNTZfRklFTERfTlVNQkVSID0gNTY7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQ2NDU2KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTY7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNTYgPSA1Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDU2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NDU2KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81N19GSUVMRF9OVU1CRVIgPSA1NzsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50MzI1NygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTcoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF81OF9GSUVMRF9OVU1CRVIgPSA1ODsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzU4ID0gNTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkNjQ1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQ2NDU4KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTg7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDU4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQzMl81OV9GSUVMRF9OVU1CRVIgPSA1OTsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEZpeGVkMzI1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQzMjU5KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjU5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMjU5KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTkpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfNjBfRklFTERfTlVNQkVSID0gNjA7CiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sNjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJvb2w2MCgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYwOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sNjAoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NUUklOR182MV9GSUVMRF9OVU1CRVIgPSA2MTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTdHJpbmc2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU3RyaW5nNjEoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nNjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIHJlZiA9IHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgICAgdGVzdE9uZW9mXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc2MS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkU3RyaW5nNjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgcmVmID0gdGVzdE9uZW9mXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBiOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUVTU0FHRV82Ml9GSUVMRF9OVU1CRVIgPSA2MjsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNZXNzYWdlNjIoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2U2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNZXNzYWdlNjIoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2U2Mk9yQnVpbGRlcigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU182M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQnl0ZXM2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXM2MygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXM2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzNjMoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDMyXzY0X0ZJRUxEX05VTUJFUiA9IDY0OwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50MzI2NCgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzI2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMjY0KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDMyXzY1X0ZJRUxEX05VTUJFUiA9IDY1OwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjY1KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMjY1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF82Nl9GSUVMRF9OVU1CRVIgPSA2NjsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkNjQ2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkNjQ2NigpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQ2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDY2KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjYpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TSU5UMzJfNjdfRklFTERfTlVNQkVSID0gNjc7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNpbnQzMjY3KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjc7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMjY3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyNjcoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0XzY4X0ZJRUxEX05VTUJFUiA9IDY4OwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50NjQ2OCgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY4OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQ2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQ2OCgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKGZpZWxkRG91YmxlMV8pICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoMSwgZmllbGREb3VibGUxXyk7CiAgICAgIH0KICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmaWVsZEZsb2F0Ml8pICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgyLCBmaWVsZEZsb2F0Ml8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEludDY0M18gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgzLCBmaWVsZEludDY0M18pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFVpbnQ2NDRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDQsIGZpZWxkVWludDY0NF8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEludDMyNV8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDUsIGZpZWxkSW50MzI1Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkRml4ZWQ2NDZfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg2LCBmaWVsZEZpeGVkNjQ2Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkRml4ZWQzMjdfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIGZpZWxkRml4ZWQzMjdfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRCb29sOF8gIT0gZmFsc2UpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDgsIGZpZWxkQm9vbDhfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkoZmllbGRTdHJpbmc5XykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDksIGZpZWxkU3RyaW5nOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTAsIGdldEZpZWxkTWVzc2FnZTEwKCkpOwogICAgICB9CiAgICAgIGlmICghZmllbGRCeXRlczExXy5pc0VtcHR5KCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygxMSwgZmllbGRCeXRlczExXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkVWludDMyMTJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMTIsIGZpZWxkVWludDMyMTJfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRFbnVtMTNfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTMsIGZpZWxkRW51bTEzXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkU2ZpeGVkMzIxNF8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDE0LCBmaWVsZFNmaXhlZDMyMTRfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRTZml4ZWQ2NDE1XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDE1LCBmaWVsZFNmaXhlZDY0MTVfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRTaW50MzIxNl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMigxNiwgZmllbGRTaW50MzIxNl8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFNpbnQ2NDE3XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgxNywgZmllbGRTaW50NjQxN18pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGREb3VibGVMaXN0MThfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDE4LCBmaWVsZERvdWJsZUxpc3QxOF8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRmxvYXRMaXN0MTlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTksIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0MjBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMjAsIGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDIxLCBmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIyLCBmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDY0TGlzdDIzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoMjMsIGZpZWxkRml4ZWQ2NExpc3QyM18uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMigyNCwgZmllbGRGaXhlZDMyTGlzdDI0Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCb29sTGlzdDI1Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMjUsIGZpZWxkQm9vbExpc3QyNV8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFN0cmluZ0xpc3QyNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI2LCBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI3LCBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEJ5dGVzTGlzdDI4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDI4LCBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0MjlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDI5LCBmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDMwLCBmaWVsZEVudW1MaXN0MzBfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDMxLCBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTZml4ZWQ2NExpc3QzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgzMiwgZmllbGRTZml4ZWQ2NExpc3QzMl8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoMzMsIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDM0LCBmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyODIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGVOb1RhZyhmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjkwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEZsb2F0TGlzdFBhY2tlZDM2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcoZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyOTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMwNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NE5vVGFnKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzE0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEludDMyTGlzdFBhY2tlZDM5TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcoZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyhmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkQm9vbExpc3RQYWNrZWQ0Mk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2xOb1RhZyhmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzU0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEVudW1MaXN0UGFja2VkNDRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM3OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRTaW50MzJMaXN0UGFja2VkNDdNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzg2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcoZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgKICAgICAgICAgICAgNTMsIChkb3VibGUpKChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoCiAgICAgICAgICAgIDU0LCAoZmxvYXQpKChqYXZhLmxhbmcuRmxvYXQpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgKICAgICAgICAgICAgNTUsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoCiAgICAgICAgICAgIDU2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDU3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KAogICAgICAgICAgICA1OCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoCiAgICAgICAgICAgIDU5LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKAogICAgICAgICAgICA2MCwgKGJvb2xlYW4pKChqYXZhLmxhbmcuQm9vbGVhbikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNjEsIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNjIsIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB0ZXN0T25lb2ZfKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygKICAgICAgICAgICAgNjMsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigKICAgICAgICAgICAgNjQsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NSkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKAogICAgICAgICAgICA2NSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY2KSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoCiAgICAgICAgICAgIDY2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY3KSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKAogICAgICAgICAgICA2NywgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KAogICAgICAgICAgICA2OCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKGZpZWxkRG91YmxlMV8pICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxLCBmaWVsZERvdWJsZTFfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKGZpZWxkRmxvYXQyXykgIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMiwgZmllbGRGbG9hdDJfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRJbnQ2NDNfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgzLCBmaWVsZEludDY0M18pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFVpbnQ2NDRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemUoNCwgZmllbGRVaW50NjQ0Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkSW50MzI1XyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg1LCBmaWVsZEludDMyNV8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEZpeGVkNjQ2XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDY0U2l6ZSg2LCBmaWVsZEZpeGVkNjQ2Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkRml4ZWQzMjdfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQzMlNpemUoNywgZmllbGRGaXhlZDMyN18pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEJvb2w4XyAhPSBmYWxzZSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg4LCBmaWVsZEJvb2w4Xyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KGZpZWxkU3RyaW5nOV8pKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg5LCBmaWVsZFN0cmluZzlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIGdldEZpZWxkTWVzc2FnZTEwKCkpOwogICAgICB9CiAgICAgIGlmICghZmllbGRCeXRlczExXy5pc0VtcHR5KCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDExLCBmaWVsZEJ5dGVzMTFfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRVaW50MzIxMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDEyLCBmaWVsZFVpbnQzMjEyXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkRW51bTEzXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTMsIGZpZWxkRW51bTEzXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkU2ZpeGVkMzIxNF8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoMTQsIGZpZWxkU2ZpeGVkMzIxNF8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFNmaXhlZDY0MTVfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgxNSwgZmllbGRTZml4ZWQ2NDE1Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkU2ludDMyMTZfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZSgxNiwgZmllbGRTaW50MzIxNl8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFNpbnQ2NDE3XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplKDE3LCBmaWVsZFNpbnQ2NDE3Xyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDY0TGlzdDIwXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZU5vVGFnKGZpZWxkVWludDY0TGlzdDIxXy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGZpZWxkSW50MzJMaXN0MjJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFN0cmluZ0xpc3QyNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcoZmllbGRTdHJpbmdMaXN0MjZfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRNZXNzYWdlTGlzdDI3Xy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNywgZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemVOb1RhZyhmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0MjlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGZpZWxkVWludDMyTGlzdDI5Xy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKGZpZWxkRW51bUxpc3QzMF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBmaWVsZEVudW1MaXN0MzBfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcoZmllbGRTaW50MzJMaXN0MzNfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZU5vVGFnKGZpZWxkU2ludDY0TGlzdDM0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0TGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9ZmllbGRFbnVtTGlzdFBhY2tlZDQ0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZU5vVGFnKGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKAogICAgICAgICAgICAgIDUzLCAoZG91YmxlKSgoamF2YS5sYW5nLkRvdWJsZSkgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoCiAgICAgICAgICAgICAgNTQsIChmbG9hdCkoKGphdmEubGFuZy5GbG9hdCkgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoCiAgICAgICAgICAgICAgNTUsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZSgKICAgICAgICAgICAgICA1NiwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgNTcsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDY0U2l6ZSgKICAgICAgICAgICAgICA1OCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSgKICAgICAgICAgICAgICA1OSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKAogICAgICAgICAgICAgIDYwLCAoYm9vbGVhbikoKGphdmEubGFuZy5Cb29sZWFuKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg2MSwgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYyLCAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgKICAgICAgICAgICAgICA2MywgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoCiAgICAgICAgICAgICAgNjQsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoCiAgICAgICAgICAgICAgNjUsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQ2NFNpemUoCiAgICAgICAgICAgICAgNjYsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZSgKICAgICAgICAgICAgICA2NywgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoCiAgICAgICAgICAgICAgNjgsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGREb3VibGUxKCkpCiAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgb3RoZXIuZ2V0RmllbGREb3VibGUxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmllbGRGbG9hdDIoKSkKICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZEZsb2F0MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRJbnQ2NDMoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQ2NDMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRVaW50NjQ0KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDY0NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZEludDMyNSgpCiAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEludDMyNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkNjQ2KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkRml4ZWQ2NDYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyNygpCiAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldEZpZWxkQm9vbDgoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRCb29sOCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTdHJpbmc5KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTdHJpbmc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2UxMCgpICE9IG90aGVyLmhhc0ZpZWxkTWVzc2FnZTEwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTEwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2UxMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0RmllbGRCeXRlczExKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlczExKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMjEyKCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDMyMTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZmllbGRFbnVtMTNfICE9IG90aGVyLmZpZWxkRW51bTEzXykgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMjE0KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkMzIxNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0MTUoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDE1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldEZpZWxkU2ludDMyMTYoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTaW50MzIxNigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NDE3KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDY0MTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRCeXRlc0xpc3QyOExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWZpZWxkRW51bUxpc3QzMF8uZXF1YWxzKG90aGVyLmZpZWxkRW51bUxpc3QzMF8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFmaWVsZEVudW1MaXN0UGFja2VkNDRfLmVxdWFscyhvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VGVzdE9uZW9mQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRUZXN0T25lb2ZDYXNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHN3aXRjaCAodGVzdE9uZW9mQ2FzZV8pIHsKICAgICAgICBjYXNlIDUzOgogICAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTUzKCkpCiAgICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZERvdWJsZTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU0OgogICAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRGaWVsZEZsb2F0NTQoKSkKICAgICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkRmxvYXQ1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NToKICAgICAgICAgIGlmIChnZXRGaWVsZEludDY0NTUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50NjQ1NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU2OgogICAgICAgICAgaWYgKGdldEZpZWxkVWludDY0NTYoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDY0NTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NzoKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyNTcoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI1NygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NDU4KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkNjQ1OCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQzMjU5KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkMzI1OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYwOgogICAgICAgICAgaWYgKGdldEZpZWxkQm9vbDYwKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEJvb2w2MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgaWYgKCFnZXRGaWVsZFN0cmluZzYxKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nNjEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjI6CiAgICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTYyKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkTWVzc2FnZTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYzOgogICAgICAgICAgaWYgKCFnZXRGaWVsZEJ5dGVzNjMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlczYzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY0OgogICAgICAgICAgaWYgKGdldEZpZWxkVWludDMyNjQoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NToKICAgICAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyNjUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkMzI2NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY2OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkNjQ2NigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDY2KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICBpZiAoZ2V0RmllbGRTaW50MzI2NygpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTaW50MzI2NygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ludDY0NjgoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDY0NjgoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9ET1VCTEVfMV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGREb3VibGUxKCkpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRkxPQVRfMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgIGdldEZpZWxkRmxvYXQyKCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQ2NF8zX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldEZpZWxkSW50NjQzKCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UNjRfNF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NDQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDY0XzZfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0RmllbGRGaXhlZDY0NigpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQzMl83X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyNygpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MXzhfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgZ2V0RmllbGRCb29sOCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HXzlfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFN0cmluZzkoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CWVRFU18xMV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXMxMSgpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQzMl8xMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyMTIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRU5VTV8xM19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkRW51bTEzXzsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyMTQoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVENjRfMTVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NDE1KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfMTZfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQzMjE2KCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF8xN19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRGaWVsZFNpbnQ2NDE3KCkpOwogICAgICBpZiAoZ2V0RmllbGREb3VibGVMaXN0MThDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0RPVUJMRV9MSVNUXzE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZsb2F0TGlzdDE5Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF9MSVNUXzE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkSW50NjRMaXN0MjBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0X0xJU1RfMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF9MSVNUXzIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDMyTGlzdDIyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl9MSVNUXzIyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQ2NF9MSVNUXzIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDMyX0xJU1RfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEJvb2xMaXN0MjVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfTElTVF8yNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU3RyaW5nTGlzdDI2Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TVFJJTkdfTElTVF8yNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NRVNTQUdFX0xJU1RfMjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEJ5dGVzTGlzdDI4Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CWVRFU19MSVNUXzI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkVWludDMyTGlzdDI5Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UMzJfTElTVF8yOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9FTlVNX0xJU1RfMzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkRW51bUxpc3QzMF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfTElTVF8zMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF9MSVNUXzMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ludDMyTGlzdDMzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfTElTVF8zM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF9MSVNUXzM0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRE9VQkxFX0xJU1RfUEFDS0VEXzM1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF9MSVNUX1BBQ0tFRF8zNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQ2NF9MSVNUX1BBQ0tFRF8zN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDY0X0xJU1RfUEFDS0VEXzM4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl9MSVNUX1BBQ0tFRF8zOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVENjRfTElTVF9QQUNLRURfNDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfTElTVF9QQUNLRURfNDFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfTElTVF9QQUNLRURfNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyX0xJU1RfUEFDS0VEXzQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0VOVU1fTElTVF9QQUNLRURfNDRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfTElTVF9QQUNLRURfNDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVENjRfTElTVF9QQUNLRURfNDZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQzMl9MSVNUX1BBQ0tFRF80N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF9MSVNUX1BBQ0tFRF80OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKHRlc3RPbmVvZkNhc2VfKSB7CiAgICAgICAgY2FzZSA1MzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0RPVUJMRV81M19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTUzKCkpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF81NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgZ2V0RmllbGRGbG9hdDU0KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0XzU1X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRJbnQ2NDU1KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF81Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkVWludDY0NTYoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU3OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfNTdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMjU3KCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQ2NF81OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkRml4ZWQ2NDU4KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1OToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyNTkoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjA6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MXzYwX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgICAgZ2V0RmllbGRCb29sNjAoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HXzYxX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU3RyaW5nNjEoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfNjJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRNZXNzYWdlNjIoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JZVEVTXzYzX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXM2MygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyXzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyNjQoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjU6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQzMl82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyNjUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjY6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF82Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkU2ZpeGVkNjQ2NigpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzI2NygpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2ODoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkU2ludDY0NjgoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMV8gPSAwOwogICAgICAgIGZpZWxkRG91YmxlMV8gPSAwRDsKICAgICAgICBmaWVsZEZsb2F0Ml8gPSAwRjsKICAgICAgICBmaWVsZEludDY0M18gPSAwTDsKICAgICAgICBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAgICAgZmllbGRJbnQzMjVfID0gMDsKICAgICAgICBmaWVsZEZpeGVkNjQ2XyA9IDBMOwogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gMDsKICAgICAgICBmaWVsZEJvb2w4XyA9IGZhbHNlOwogICAgICAgIGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgZmllbGRVaW50MzIxMl8gPSAwOwogICAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IDA7CiAgICAgICAgZmllbGRTZml4ZWQ2NDE1XyA9IDBMOwogICAgICAgIGZpZWxkU2ludDMyMTZfID0gMDsKICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBmaWVsZEludDY0TGlzdDIwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG51bGw7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdDM0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMV8gIT0gMCkgeyBidWlsZFBhcnRpYWwxKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRNZXNzYWdlTGlzdDI3Xyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5maWVsZE1lc3NhZ2VMaXN0MjdfID0gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWVzc2FnZUxpc3QyN18gPSBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZEVudW1MaXN0MzBfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmZpZWxkRW51bUxpc3QzMF8gPSBmaWVsZEVudW1MaXN0MzBfOwogICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8pOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQuZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZERvdWJsZTFfID0gZmllbGREb3VibGUxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEZsb2F0Ml8gPSBmaWVsZEZsb2F0Ml87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQ2NDNfID0gZmllbGRJbnQ2NDNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDY0NF8gPSBmaWVsZFVpbnQ2NDRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI1XyA9IGZpZWxkSW50MzI1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkNjQ2XyA9IGZpZWxkRml4ZWQ2NDZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQzMjdfID0gZmllbGRGaXhlZDMyN187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRCb29sOF8gPSBmaWVsZEJvb2w4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFN0cmluZzlfID0gZmllbGRTdHJpbmc5XzsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNZXNzYWdlMTBfID0gZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmaWVsZE1lc3NhZ2UxMF8KICAgICAgICAgICAgICA6IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEJ5dGVzMTFfID0gZmllbGRCeXRlczExXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQzMjEyXyA9IGZpZWxkVWludDMyMTJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRW51bTEzXyA9IGZpZWxkRW51bTEzXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDMyMTRfID0gZmllbGRTZml4ZWQzMjE0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDY0MTVfID0gZmllbGRTZml4ZWQ2NDE1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQzMjE2XyA9IGZpZWxkU2ludDMyMTZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDY0MTdfID0gZmllbGRTaW50NjQxN187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRG91YmxlTGlzdDE4XyA9IGZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZsb2F0TGlzdDE5XyA9IGZpZWxkRmxvYXRMaXN0MTlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkSW50NjRMaXN0MjBfID0gZmllbGRJbnQ2NExpc3QyMF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDY0TGlzdDIxXyA9IGZpZWxkVWludDY0TGlzdDIxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyTGlzdDIyXyA9IGZpZWxkSW50MzJMaXN0MjJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDY0TGlzdDIzXyA9IGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkMzJMaXN0MjRfID0gZmllbGRGaXhlZDMyTGlzdDI0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkQm9vbExpc3QyNV8gPSBmaWVsZEJvb2xMaXN0MjVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFN0cmluZ0xpc3QyNl8gPSBmaWVsZFN0cmluZ0xpc3QyNl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRCeXRlc0xpc3QyOF8gPSBmaWVsZEJ5dGVzTGlzdDI4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50MzJMaXN0MjlfID0gZmllbGRVaW50MzJMaXN0MjlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQzMkxpc3QzM18gPSBmaWVsZFNpbnQzMkxpc3QzM187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDY0TGlzdDM0XyA9IGZpZWxkU2ludDY0TGlzdDM0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gZmllbGREb3VibGVMaXN0UGFja2VkMzVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPSBmaWVsZEludDY0TGlzdFBhY2tlZDM3XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gZmllbGRTaW50NjRMaXN0UGFja2VkNDhfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIHJlc3VsdC50ZXN0T25lb2ZDYXNlXyA9IHRlc3RPbmVvZkNhc2VfOwogICAgICAgIHJlc3VsdC50ZXN0T25lb2ZfID0gdGhpcy50ZXN0T25lb2ZfOwogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MiAmJgogICAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlc3VsdC50ZXN0T25lb2ZfID0gZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGREb3VibGUxKCkgIT0gMEQpIHsKICAgICAgICAgIHNldEZpZWxkRG91YmxlMShvdGhlci5nZXRGaWVsZERvdWJsZTEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRGaWVsZEZsb2F0MigpICE9IDBGKSB7CiAgICAgICAgICBzZXRGaWVsZEZsb2F0MihvdGhlci5nZXRGaWVsZEZsb2F0MigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkSW50NjQzKCkgIT0gMEwpIHsKICAgICAgICAgIHNldEZpZWxkSW50NjQzKG90aGVyLmdldEZpZWxkSW50NjQzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRVaW50NjQ0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldEZpZWxkVWludDY0NChvdGhlci5nZXRGaWVsZFVpbnQ2NDQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRGaWVsZEludDMyNSgpICE9IDApIHsKICAgICAgICAgIHNldEZpZWxkSW50MzI1KG90aGVyLmdldEZpZWxkSW50MzI1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRGaXhlZDY0NigpICE9IDBMKSB7CiAgICAgICAgICBzZXRGaWVsZEZpeGVkNjQ2KG90aGVyLmdldEZpZWxkRml4ZWQ2NDYoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkgIT0gMCkgewogICAgICAgICAgc2V0RmllbGRGaXhlZDMyNyhvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRCb29sOCgpICE9IGZhbHNlKSB7CiAgICAgICAgICBzZXRGaWVsZEJvb2w4KG90aGVyLmdldEZpZWxkQm9vbDgoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0RmllbGRTdHJpbmc5KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gb3RoZXIuZmllbGRTdHJpbmc5XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZE1lc3NhZ2UxMChvdGhlci5nZXRGaWVsZE1lc3NhZ2UxMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkQnl0ZXMxMSgpICE9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSkgewogICAgICAgICAgc2V0RmllbGRCeXRlczExKG90aGVyLmdldEZpZWxkQnl0ZXMxMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkVWludDMyMTIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRGaWVsZFVpbnQzMjEyKG90aGVyLmdldEZpZWxkVWludDMyMTIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5maWVsZEVudW0xM18gIT0gMCkgewogICAgICAgICAgc2V0RmllbGRFbnVtMTNWYWx1ZShvdGhlci5nZXRGaWVsZEVudW0xM1ZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRTZml4ZWQzMjE0KCkgIT0gMCkgewogICAgICAgICAgc2V0RmllbGRTZml4ZWQzMjE0KG90aGVyLmdldEZpZWxkU2ZpeGVkMzIxNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkU2ZpeGVkNjQxNSgpICE9IDBMKSB7CiAgICAgICAgICBzZXRGaWVsZFNmaXhlZDY0MTUob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDE1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRTaW50MzIxNigpICE9IDApIHsKICAgICAgICAgIHNldEZpZWxkU2ludDMyMTYob3RoZXIuZ2V0RmllbGRTaW50MzIxNigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkU2ludDY0MTcoKSAhPSAwTCkgewogICAgICAgICAgc2V0RmllbGRTaW50NjQxNyhvdGhlci5nZXRGaWVsZFNpbnQ2NDE3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRG91YmxlTGlzdDE4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZERvdWJsZUxpc3QxOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IG90aGVyLmZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLmFkZEFsbChvdGhlci5maWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGbG9hdExpc3QxOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGbG9hdExpc3QxOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gb3RoZXIuZmllbGRGbG9hdExpc3QxOV87CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRBbGwob3RoZXIuZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQ2NExpc3QyMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQ2NExpc3QyMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gb3RoZXIuZmllbGRJbnQ2NExpc3QyMF87CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5hZGRBbGwob3RoZXIuZmllbGRJbnQ2NExpc3QyMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50NjRMaXN0MjFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDY0TGlzdDIxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfID0gb3RoZXIuZmllbGRVaW50NjRMaXN0MjFfOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uYWRkQWxsKG90aGVyLmZpZWxkVWludDY0TGlzdDIxXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEludDMyTGlzdDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEludDMyTGlzdDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBvdGhlci5maWVsZEludDMyTGlzdDIyXzsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEFsbChvdGhlci5maWVsZEludDMyTGlzdDIyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRml4ZWQ2NExpc3QyM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkQWxsKG90aGVyLmZpZWxkRml4ZWQ2NExpc3QyM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkMzJMaXN0MjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gb3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0XzsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQm9vbExpc3QyNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRCb29sTGlzdDI1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG90aGVyLmZpZWxkQm9vbExpc3QyNV87CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1Xy5hZGRBbGwob3RoZXIuZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFN0cmluZ0xpc3QyNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTdHJpbmdMaXN0MjZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPSBvdGhlci5maWVsZFN0cmluZ0xpc3QyNl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGRBbGwob3RoZXIuZmllbGRTdHJpbmdMaXN0MjZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGRBbGwob3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG90aGVyLmZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkQnl0ZXNMaXN0MjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IG90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfOwogICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uYWRkQWxsKG90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkVWludDMyTGlzdDI5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFVpbnQzMkxpc3QyOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5XyA9IG90aGVyLmZpZWxkVWludDMyTGlzdDI5XzsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEFsbChvdGhlci5maWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRFbnVtTGlzdDMwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEVudW1MaXN0MzBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gb3RoZXIuZmllbGRFbnVtTGlzdDMwXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkQWxsKG90aGVyLmZpZWxkRW51bUxpc3QzMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gb3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5hZGRBbGwob3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gb3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRBbGwob3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50MzJMaXN0MzNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDMyTGlzdDMzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gb3RoZXIuZmllbGRTaW50MzJMaXN0MzNfOwogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uYWRkQWxsKG90aGVyLmZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFNpbnQ2NExpc3QzNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTaW50NjRMaXN0MzRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBvdGhlci5maWVsZFNpbnQ2NExpc3QzNF87CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRBbGwob3RoZXIuZmllbGRTaW50NjRMaXN0MzRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IG90aGVyLmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZEFsbChvdGhlci5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gb3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRBbGwob3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gb3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRBbGwob3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gb3RoZXIuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkQWxsKG90aGVyLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEFsbChvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkQWxsKG90aGVyLmZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gb3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRCb29sTGlzdFBhY2tlZDQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IG90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRBbGwob3RoZXIuZmllbGRCb29sTGlzdFBhY2tlZDQyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBvdGhlci5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRBbGwob3RoZXIuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IG90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZEFsbChvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9IG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9IG90aGVyLmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0UGFja2VkNDdJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEFsbChvdGhlci5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gb3RoZXIuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkQWxsKG90aGVyLmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRUZXN0T25lb2ZDYXNlKCkpIHsKICAgICAgICAgIGNhc2UgRklFTERfRE9VQkxFXzUzOiB7CiAgICAgICAgICAgIHNldEZpZWxkRG91YmxlNTMob3RoZXIuZ2V0RmllbGREb3VibGU1MygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0ZMT0FUXzU0OiB7CiAgICAgICAgICAgIHNldEZpZWxkRmxvYXQ1NChvdGhlci5nZXRGaWVsZEZsb2F0NTQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9JTlQ2NF81NTogewogICAgICAgICAgICBzZXRGaWVsZEludDY0NTUob3RoZXIuZ2V0RmllbGRJbnQ2NDU1KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfVUlOVDY0XzU2OiB7CiAgICAgICAgICAgIHNldEZpZWxkVWludDY0NTYob3RoZXIuZ2V0RmllbGRVaW50NjQ1NigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0lOVDMyXzU3OiB7CiAgICAgICAgICAgIHNldEZpZWxkSW50MzI1NyhvdGhlci5nZXRGaWVsZEludDMyNTcoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9GSVhFRDY0XzU4OiB7CiAgICAgICAgICAgIHNldEZpZWxkRml4ZWQ2NDU4KG90aGVyLmdldEZpZWxkRml4ZWQ2NDU4KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfRklYRUQzMl81OTogewogICAgICAgICAgICBzZXRGaWVsZEZpeGVkMzI1OShvdGhlci5nZXRGaWVsZEZpeGVkMzI1OSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0JPT0xfNjA6IHsKICAgICAgICAgICAgc2V0RmllbGRCb29sNjAob3RoZXIuZ2V0RmllbGRCb29sNjAoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TVFJJTkdfNjE6IHsKICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG90aGVyLnRlc3RPbmVvZl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfTUVTU0FHRV82MjogewogICAgICAgICAgICBtZXJnZUZpZWxkTWVzc2FnZTYyKG90aGVyLmdldEZpZWxkTWVzc2FnZTYyKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfQllURVNfNjM6IHsKICAgICAgICAgICAgc2V0RmllbGRCeXRlczYzKG90aGVyLmdldEZpZWxkQnl0ZXM2MygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1VJTlQzMl82NDogewogICAgICAgICAgICBzZXRGaWVsZFVpbnQzMjY0KG90aGVyLmdldEZpZWxkVWludDMyNjQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TRklYRUQzMl82NTogewogICAgICAgICAgICBzZXRGaWVsZFNmaXhlZDMyNjUob3RoZXIuZ2V0RmllbGRTZml4ZWQzMjY1KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfU0ZJWEVENjRfNjY6IHsKICAgICAgICAgICAgc2V0RmllbGRTZml4ZWQ2NDY2KG90aGVyLmdldEZpZWxkU2ZpeGVkNjQ2NigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1NJTlQzMl82NzogewogICAgICAgICAgICBzZXRGaWVsZFNpbnQzMjY3KG90aGVyLmdldEZpZWxkU2ludDMyNjcoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TSU5UNjRfNjg6IHsKICAgICAgICAgICAgc2V0RmllbGRTaW50NjQ2OChvdGhlci5nZXRGaWVsZFNpbnQ2NDY4KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgVEVTVE9ORU9GX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgOTogewogICAgICAgICAgICAgICAgZmllbGREb3VibGUxXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5CiAgICAgICAgICAgICAgY2FzZSAyMTogewogICAgICAgICAgICAgICAgZmllbGRGbG9hdDJfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDY0M18gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGZpZWxkVWludDY0NF8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDMyNV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDk6IHsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NDZfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OQogICAgICAgICAgICAgIGNhc2UgNjE6IHsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQzMjdfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbDhfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NAogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkU3RyaW5nOV8gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkVWludDMyMTJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkRW51bTEzXyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMTc6IHsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzIxNF8gPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTcKICAgICAgICAgICAgICBjYXNlIDEyMTogewogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NDE1XyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMQogICAgICAgICAgICAgIGNhc2UgMTI4OiB7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMjE2XyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjgKICAgICAgICAgICAgICBjYXNlIDEzNjogewogICAgICAgICAgICAgICAgZmllbGRTaW50NjQxN18gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2CiAgICAgICAgICAgICAgY2FzZSAxNDU6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ1CiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTc6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NwogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjA6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAKICAgICAgICAgICAgICBjYXNlIDE2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTY4OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzAKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODU6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODUKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk3CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDA6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDAKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTdHJpbmdMaXN0MjZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQocyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjE4CiAgICAgICAgICAgICAgY2FzZSAyMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2ID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJ5dGVzTGlzdDI4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5hZGQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjI2CiAgICAgICAgICAgICAgY2FzZSAyMzI6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjMyCiAgICAgICAgICAgICAgY2FzZSAyMzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIzNAogICAgICAgICAgICAgIGNhc2UgMjQwOiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRFbnVtTGlzdDMwXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNDAKICAgICAgICAgICAgICBjYXNlIDI0MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MgogICAgICAgICAgICAgIGNhc2UgMjUzOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MwogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MAogICAgICAgICAgICAgIGNhc2UgMjU3OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU3CiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1OAogICAgICAgICAgICAgIGNhc2UgMjY0OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NAogICAgICAgICAgICAgIGNhc2UgMjY2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNjYKICAgICAgICAgICAgICBjYXNlIDI3MjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3MgogICAgICAgICAgICAgIGNhc2UgMjc0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjc0CiAgICAgICAgICAgICAgY2FzZSAyODE6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgxCiAgICAgICAgICAgICAgY2FzZSAyODI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyOTM6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MwogICAgICAgICAgICAgIGNhc2UgMjkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjkwCiAgICAgICAgICAgICAgY2FzZSAyOTY6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTYKICAgICAgICAgICAgICBjYXNlIDI5ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA0OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA0CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDYKICAgICAgICAgICAgICBjYXNlIDMxMjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMTIKICAgICAgICAgICAgICBjYXNlIDMxNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE0CiAgICAgICAgICAgICAgY2FzZSAzMjE6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjEKICAgICAgICAgICAgICBjYXNlIDMyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIyCiAgICAgICAgICAgICAgY2FzZSAzMzM6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMzCiAgICAgICAgICAgICAgY2FzZSAzMzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMwCiAgICAgICAgICAgICAgY2FzZSAzMzY6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzYKICAgICAgICAgICAgICBjYXNlIDMzODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM4CiAgICAgICAgICAgICAgY2FzZSAzNDQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ0CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgMzUyOiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTIKICAgICAgICAgICAgICBjYXNlIDM1NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM1NAogICAgICAgICAgICAgIGNhc2UgMzY1OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2NQogICAgICAgICAgICAgIGNhc2UgMzYyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2MgogICAgICAgICAgICAgIGNhc2UgMzY5OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzY5CiAgICAgICAgICAgICAgY2FzZSAzNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3MAogICAgICAgICAgICAgIGNhc2UgMzc2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3NgogICAgICAgICAgICAgIGNhc2UgMzc4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzgKICAgICAgICAgICAgICBjYXNlIDM4NDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM4NAogICAgICAgICAgICAgIGNhc2UgMzg2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzg2CiAgICAgICAgICAgICAgY2FzZSA0MjU6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDUzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyNQogICAgICAgICAgICAgIGNhc2UgNDM3OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQzNwogICAgICAgICAgICAgIGNhc2UgNDQwOiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU1OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0MAogICAgICAgICAgICAgIGNhc2UgNDQ4OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NDgKICAgICAgICAgICAgICBjYXNlIDQ1NjogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NTYKICAgICAgICAgICAgICBjYXNlIDQ2NTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ2NQogICAgICAgICAgICAgIGNhc2UgNDc3OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDc3CiAgICAgICAgICAgICAgY2FzZSA0ODA6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0ODAKICAgICAgICAgICAgICBjYXNlIDQ5MDogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYxOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IHM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDkwCiAgICAgICAgICAgICAgY2FzZSA0OTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTYyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDk4CiAgICAgICAgICAgICAgY2FzZSA1MDY6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTA2CiAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxMgogICAgICAgICAgICAgIGNhc2UgNTI1OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY1OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyNQogICAgICAgICAgICAgIGNhc2UgNTI5OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY2OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyOQogICAgICAgICAgICAgIGNhc2UgNTM2OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MzYKICAgICAgICAgICAgICBjYXNlIDU0NDogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTQ0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgdGVzdE9uZW9mXzsKICAgICAgcHVibGljIFRlc3RPbmVvZkNhc2UKICAgICAgICAgIGdldFRlc3RPbmVvZkNhc2UoKSB7CiAgICAgICAgcmV0dXJuIFRlc3RPbmVvZkNhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVGVzdE9uZW9mKCkgewogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKCiAgICAgIHByaXZhdGUgZG91YmxlIGZpZWxkRG91YmxlMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTEoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRG91YmxlMShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZmllbGREb3VibGUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGREb3VibGUxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBmaWVsZERvdWJsZTFfID0gMEQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgZmllbGRGbG9hdDJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0MigpIHsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdDJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZsb2F0MihmbG9hdCB2YWx1ZSkgewoKICAgICAgICBmaWVsZEZsb2F0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZsb2F0MigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZmllbGRGbG9hdDJfID0gMEY7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZEludDY0M18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NDMoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjQzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NDMobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZEludDY0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZmllbGRJbnQ2NDNfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZFVpbnQ2NDRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0NCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjQ0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjQ0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRVaW50NjQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50NjQ0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBmaWVsZFVpbnQ2NDRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkSW50MzI1XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzI1KCkgewogICAgICAgIHJldHVybiBmaWVsZEludDMyNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDMyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzI1KGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZEludDMyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyNSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgZmllbGRJbnQzMjVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkRml4ZWQ2NDZfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkRml4ZWQ2NDYoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NDZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjQ2KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDY0NigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRGaXhlZDMyN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzI3KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzI3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzcgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkMzI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyNyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGaXhlZDMyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDMyNygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgZmllbGRGaXhlZDMyN18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gZmllbGRCb29sOF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCb29sOC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sOCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQm9vbDgoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBmaWVsZEJvb2w4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2w4KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBmaWVsZEJvb2w4XyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZmllbGRTdHJpbmc5XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTdHJpbmc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZmllbGRTdHJpbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmc5KCkgewogICAgICAgIGZpZWxkU3RyaW5nOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZFN0cmluZzkoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBmaWVsZFN0cmluZzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZmllbGRNZXNzYWdlMTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1lc3NhZ2UxMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2UxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWVzc2FnZTEwKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZE1lc3NhZ2UxMF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlMTAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2UxMCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRNZXNzYWdlMTAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gIT0gbnVsbCAmJgogICAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2UxMEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIGdldEZpZWxkTWVzc2FnZTEwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTEwT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlMTBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzMTFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzMTEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZEJ5dGVzMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJ5dGVzMTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZEJ5dGVzMTEoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRVaW50MzIxMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzIxMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMjEyKCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMjEyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMjEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzIxMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRVaW50MzIxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzIxMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgZmllbGRVaW50MzIxMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZEVudW0xM18gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtMTMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtMTNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZmllbGRFbnVtMTNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bTEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRFbnVtMTNWYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBmaWVsZEVudW0xM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW0xMy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtMTMoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZEVudW0xM18pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEVudW0xMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bTEzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBmaWVsZEVudW0xM18gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRFbnVtMTMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkMzIxNF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzIxNC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyMTQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzIxNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzIxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkMzIxNChpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQzMjE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ZpeGVkNjQxNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQxNS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDE1KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0MTUobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFNmaXhlZDY0MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGZpZWxkU2ZpeGVkNjQxNV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50MzIxNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzIxNi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMjE2KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMjE2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMjE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzIxNihpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRTaW50MzIxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzIxNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgZmllbGRTaW50MzIxNl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRTaW50NjQxN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50NjQxN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjQxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ludDY0MTcobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NDE3KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3QxOF8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGREb3VibGVMaXN0MThfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGREb3VibGVMaXN0MThfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRG91YmxlTGlzdDE4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0MThfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRG91YmxlTGlzdDE4XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZERvdWJsZUxpc3QxOENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdDE4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0MTgoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdDE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGVMaXN0MTgoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdDE4IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGREb3VibGVMaXN0MTgoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGREb3VibGVMaXN0MTggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZERvdWJsZUxpc3QxOCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGREb3VibGVMaXN0MThfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlTGlzdDE4KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdDE5XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdDE5SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3QxOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0MTlfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdDE5SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3QxOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0MTlfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkgewogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGbG9hdExpc3QxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdDE5Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0MTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0MTkoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdExpc3QxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRmxvYXRMaXN0MTkoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXRMaXN0MTkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZsb2F0TGlzdDE5KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRmxvYXRMaXN0MTkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZsb2F0TGlzdDE5KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRmxvYXRMaXN0MTkoKSB7CiAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkSW50NjRMaXN0MjBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkSW50NjRMaXN0MjBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEludDY0TGlzdDIwXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDY0TGlzdDIwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRJbnQ2NExpc3QyMExpc3QoKSB7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdDIwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdDIwLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDY0TGlzdDIwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3QyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdDIwXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NExpc3QyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjRMaXN0MjAoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0TGlzdDIwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRJbnQ2NExpc3QyMChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0MjBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRJbnQ2NExpc3QyMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkSW50NjRMaXN0MjAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkSW50NjRMaXN0MjBfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0TGlzdDIwKCkgewogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRVaW50NjRMaXN0MjFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRVaW50NjRMaXN0MjFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKSB7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDY0TGlzdDIxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0MjEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0TGlzdDIxKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0TGlzdDIxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRVaW50NjRMaXN0MjEobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdDIxXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkVWludDY0TGlzdDIxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRVaW50NjRMaXN0MjFfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0TGlzdDIxKCkgewogICAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkSW50MzJMaXN0MjJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRJbnQzMkxpc3QyMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkSW50MzJMaXN0MjJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpIHsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0MjJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0MjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyTGlzdDIyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3QyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzJMaXN0MjIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3QyMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkSW50MzJMaXN0MjIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEludDMyTGlzdDIyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRJbnQzMkxpc3QyMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRJbnQzMkxpc3QyMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzJMaXN0MjIoKSB7CiAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEZpeGVkNjRMaXN0MjNfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDY0TGlzdDIzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkNjRMaXN0MjNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkNjRMaXN0MjNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQ2NExpc3QyM18sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0MjMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM18uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjRMaXN0MjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjRMaXN0MjMoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRml4ZWQ2NExpc3QyMyhsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkNjRMaXN0MjMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkNjRMaXN0MjMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDY0TGlzdDIzXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQ2NExpc3QyMygpIHsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRGaXhlZDMyTGlzdDI0XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDMyTGlzdDI0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDMyTGlzdDI0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkMzJMaXN0MjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQzMkxpc3QyNF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMkxpc3QyNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdDI0Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyTGlzdDI0KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdDI0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGaXhlZDMyTGlzdDI0KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkMzJMaXN0MjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDMyTGlzdDI0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMkxpc3QyNCgpIHsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdDI1XyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkQm9vbExpc3QyNV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRCb29sTGlzdDI1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJvb2xMaXN0MjVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpIHsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdDI1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEJvb2xMaXN0MjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2xMaXN0MjUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sTGlzdDI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sTGlzdDI1KAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQm9vbExpc3QyNV8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2xMaXN0MjUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEJvb2xMaXN0MjUoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRCb29sTGlzdDI1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRCb29sTGlzdDI1KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkQm9vbExpc3QyNV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2xMaXN0MjUoKSB7CiAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU3RyaW5nTGlzdDI2Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChmaWVsZFN0cmluZ0xpc3QyNl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFN0cmluZ0xpc3QyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkgewogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nTGlzdDI2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFN0cmluZ0xpc3QyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU3RyaW5nTGlzdDI2KAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTdHJpbmdMaXN0MjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRTdHJpbmdMaXN0MjYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRTdHJpbmdMaXN0MjZJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRTdHJpbmdMaXN0MjZfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU3RyaW5nTGlzdDI2KCkgewogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTdHJpbmdMaXN0MjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBmaWVsZE1lc3NhZ2VMaXN0MjdfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3TGlzdCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCBmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1lc3NhZ2VMaXN0MjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWVzc2FnZUxpc3QyNyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEJ5dGVzTGlzdDI4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCeXRlc0xpc3QyOF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCeXRlc0xpc3QyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpIHsKICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkQnl0ZXNMaXN0MjhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkQnl0ZXNMaXN0MjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzTGlzdDI4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlc0xpc3QyOChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCeXRlc0xpc3QyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQnl0ZXNMaXN0MjgoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQnl0ZXNMaXN0MjggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEJ5dGVzTGlzdDI4KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkQnl0ZXNMaXN0MjggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEJ5dGVzTGlzdDI4KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRCeXRlc0xpc3QyOF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQnl0ZXNMaXN0MjgoKSB7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdDI5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFVpbnQzMkxpc3QyOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQzMkxpc3QyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpIHsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3QyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDMyTGlzdDI5KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkVWludDMyTGlzdDI5KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkVWludDMyTGlzdDI5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRVaW50MzJMaXN0MjkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzJMaXN0MjkoKSB7CiAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0MzBfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihmaWVsZEVudW1MaXN0MzBfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdDMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3QzMExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdDMwXywgZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3QzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0MzBfY29udmVydGVyXy5jb252ZXJ0KGZpZWxkRW51bUxpc3QzMF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3QzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bUxpc3QzMCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdDMwXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3QzMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3QzMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRFbnVtTGlzdDMwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdDMwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEVudW1MaXN0MzAoKSB7CiAgICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdDMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZEVudW1MaXN0MzBWYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkRW51bUxpc3QzMF8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3QzMFZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0MzBfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdDMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRFbnVtTGlzdDMwVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3QzMF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3QzMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3QzMFZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0MzAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEVudW1MaXN0MzBWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0MzFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0MzFfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3QzMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyTGlzdDMxKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNmaXhlZDMyTGlzdDMxKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQzMkxpc3QzMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkMzJMaXN0MzEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdDMxSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkMzJMaXN0MzFfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyTGlzdDMxKCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0MzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjRMaXN0MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQ2NExpc3QzMihsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkNjRMaXN0MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkNjRMaXN0MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0TGlzdDMyKCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0MzNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDMyTGlzdDMzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdDMzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdDMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzJMaXN0MzMoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdDMzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTaW50MzJMaXN0MzMoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50MzJMaXN0MzMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQzMkxpc3QzMygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdDMzSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMkxpc3QzMygpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDY0TGlzdDM0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDY0TGlzdDM0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdDM0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3QzNENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdDM0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdDM0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0MzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NExpc3QzNCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NExpc3QzNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDY0TGlzdDM0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50NjRMaXN0MzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQ2NExpc3QzNCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDY0TGlzdDM0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NExpc3QzNCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGREb3VibGVMaXN0UGFja2VkMzVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGVMaXN0UGFja2VkMzUoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGREb3VibGVMaXN0UGFja2VkMzUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZERvdWJsZUxpc3RQYWNrZWQzNSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGREb3VibGVMaXN0UGFja2VkMzVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkgewogICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRmxvYXRMaXN0UGFja2VkMzYoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRmxvYXRMaXN0UGFja2VkMzYoKSB7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEludDY0TGlzdFBhY2tlZDM3Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKSB7CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjRMaXN0UGFja2VkMzcoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRJbnQ2NExpc3RQYWNrZWQzNyhsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkSW50NjRMaXN0UGFja2VkMzcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0TGlzdFBhY2tlZDM3KCkgewogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRVaW50NjRMaXN0UGFja2VkMzhfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOExpc3QoKSB7CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzgoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRVaW50NjRMaXN0UGFja2VkMzgobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0TGlzdFBhY2tlZDM4KCkgewogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkSW50MzJMaXN0UGFja2VkMzlfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpIHsKICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzJMaXN0UGFja2VkMzkoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkSW50MzJMaXN0UGFja2VkMzkoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRJbnQzMkxpc3RQYWNrZWQzOSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0UGFja2VkMzlJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzJMaXN0UGFja2VkMzkoKSB7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MCgpIHsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSgpIHsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCb29sTGlzdFBhY2tlZDQyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRCb29sTGlzdFBhY2tlZDQyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJvb2xMaXN0UGFja2VkNDJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpIHsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2xMaXN0UGFja2VkNDIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sTGlzdFBhY2tlZDQyKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2xMaXN0UGFja2VkNDIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEJvb2xMaXN0UGFja2VkNDIoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRCb29sTGlzdFBhY2tlZDQyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2xMaXN0UGFja2VkNDIoKSB7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpIHsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0UGFja2VkNDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRVaW50MzJMaXN0UGFja2VkNDMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzJMaXN0UGFja2VkNDMoKSB7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0UGFja2VkNDRfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihmaWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdFBhY2tlZDQ0XywgZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfY29udmVydGVyXy5jb252ZXJ0KGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bUxpc3RQYWNrZWQ0NCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3RQYWNrZWQ0NChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdFBhY2tlZDQ0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEVudW1MaXN0UGFja2VkNDQoKSB7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRWYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0VmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0UGFja2VkNDQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEVudW1MaXN0UGFja2VkNDRWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nihsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV81MyA9IDUzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRG91YmxlNTMoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDUzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTUzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGU1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRG91YmxlNTMoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTM7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlNTMoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDUzKSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZsb2F0NTQoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXQ1NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTQpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEY7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXQ1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRmxvYXQ1NChmbG9hdCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU0OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdDU0KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQ2NDU1KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjQ1NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NDU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NDU1KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50NjQ1NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NDU2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0NTYoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDU2LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NDU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjQ1Nihsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTY7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0NTYoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTcoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU3OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjU3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTcoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjU3KGludCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU3OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMjU3KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDY0NTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDY0NTgoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDU4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0NTgoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEw7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjQ1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQ2NDU4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1ODsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQzMjU5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQzMjU5KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1OTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyNTkoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQzMjU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyNTkoaW50IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTk7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDMyNTkoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w2MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJvb2w2MCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2w2MCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbDYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sNjAoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYwOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQm9vbDYwKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MCkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZzYxKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmc2MS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc2MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgICAgcmVmID0gdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc2MS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmc2MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmc2MSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc2MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjE7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IGZpZWxkTWVzc2FnZTYyQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1lc3NhZ2U2MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTYyKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTYyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB0ZXN0T25lb2ZfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlNjIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlNjIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgdGVzdE9uZW9mXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZE1lc3NhZ2U2Mihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyICYmCiAgICAgICAgICAgICAgdGVzdE9uZW9mXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHRlc3RPbmVvZl8pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWVzc2FnZTYyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlNjJCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1lc3NhZ2U2MkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTYyT3JCdWlsZGVyKCkgewogICAgICAgIGlmICgodGVzdE9uZW9mQ2FzZV8gPT0gNjIpICYmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHRlc3RPbmVvZl87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSBmaWVsZF9tZXNzYWdlXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTYyRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKHRlc3RPbmVvZkNhc2VfID09IDYyKSkgewogICAgICAgICAgICB0ZXN0T25lb2ZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdGVzdE9uZW9mXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXM2MygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXM2MygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzNjMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYzOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCeXRlczYzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyNjQoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NDsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzI2NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyNjUoaW50IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjU7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyNjUoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkNjQ2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDY2LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDY2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0NjYobG9uZyB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY2OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQ2NDY2KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzI2NygpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjc7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyNjcoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY3KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMjY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzI2NyhpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NzsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzI2NygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0NjgoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQ2OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NDY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjQ2OChsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjg7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ludDY0NjgoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzNNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFByb3RvM01lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBQcm90bzNNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzNNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUHJvdG8zRW1wdHlPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM0VtcHR5KQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zRW1wdHl9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm90bzNFbXB0eSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zRW1wdHkpCiAgICAgIFByb3RvM0VtcHR5T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQcm90bzNFbXB0eS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzNFbXB0eShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvM0VtcHR5KCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvM0VtcHR5KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNFbXB0eV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5KSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNFbXB0eX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNFbXB0eSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNFbXB0eSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM0VtcHR5KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zRW1wdHkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM0VtcHR5IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zRW1wdHk+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8zRW1wdHk+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBQcm90bzNFbXB0eSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM0VtcHR5PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM0VtcHR5PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNFbXB0eSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFByb3RvM01lc3NhZ2VXaXRoTWFwc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sQm9vbDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xCb29sMSgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEJvb2xCb29sMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwQm9vbEJvb2wxT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwQm9vbEJvb2wxT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEJ5dGVzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sQnl0ZXMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRG91YmxlM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xEb3VibGUzKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEJvb2xEb3VibGUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEJvb2xEb3VibGUzT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xFbnVtNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZsb2F0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sSW50NjQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sVWludDY0MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDY0MzQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjREb3VibGUzNygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0SW50NjQ0MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkJvb2w1MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50MzJCeXRlczUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJEb3VibGU1NCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwSW50MzJEb3VibGU1NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwSW50MzJEb3VibGU1NE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPclRocm93KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRmxvYXQ1OCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMySW50MzI1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyVWludDMyNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyVWludDY0NjhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0SW50NjQ3N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0VWludDMyODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0VWludDY0ODVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMySW50MzI5MygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTaW50MzIxMzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJVaW50NjQxMzYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRG91YmxlMTczTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPclRocm93KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMySW50NjQxNzlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTaW50NjQxODQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0SW50MzIxOTUoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0VWludDMyMjAzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvdG8zTWVzc2FnZVdpdGhNYXBzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMpCiAgICAgIFByb3RvM01lc3NhZ2VXaXRoTWFwc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUHJvdG8zTWVzc2FnZVdpdGhNYXBzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFByb3RvM01lc3NhZ2VXaXRoTWFwcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFByb3RvM01lc3NhZ2VXaXRoTWFwcygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBQcm90bzNNZXNzYWdlV2l0aE1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpOwogICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgIGNhc2UgMTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpOwogICAgICAgIGNhc2UgMTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgIGNhc2UgMTg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICBjYXNlIDE5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpOwogICAgICAgIGNhc2UgMjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgIGNhc2UgMjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICBjYXNlIDIyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCk7CiAgICAgICAgY2FzZSAyMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgY2FzZSAyNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKTsKICAgICAgICBjYXNlIDI2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgIGNhc2UgMjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICBjYXNlIDI4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgICAgIGNhc2UgMjk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgY2FzZSAzMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgY2FzZSAzMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAgICAgY2FzZSAzMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgY2FzZSAzMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgY2FzZSAzNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCk7CiAgICAgICAgY2FzZSAzNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgIGNhc2UgMzY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgY2FzZSAzNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCk7CiAgICAgICAgY2FzZSAzODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgIGNhc2UgMzk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICBjYXNlIDQwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCk7CiAgICAgICAgY2FzZSA0MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICBjYXNlIDQyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgIGNhc2UgNDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAgICAgY2FzZSA0NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgIGNhc2UgNDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgY2FzZSA0NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKTsKICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICBjYXNlIDQ4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICBjYXNlIDQ5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKTsKICAgICAgICBjYXNlIDUwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICBjYXNlIDUxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICBjYXNlIDUyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpOwogICAgICAgIGNhc2UgNTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICBjYXNlIDU1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpOwogICAgICAgIGNhc2UgNTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgY2FzZSA1NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKTsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICBjYXNlIDYwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpOwogICAgICAgIGNhc2UgNjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgIGNhc2UgNjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgIGNhc2UgNjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKTsKICAgICAgICBjYXNlIDY1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgY2FzZSA2NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKTsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgY2FzZSA2OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICBjYXNlIDcwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKTsKICAgICAgICBjYXNlIDcxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgY2FzZSA3MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICBjYXNlIDczOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgY2FzZSA3NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgY2FzZSA3NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCk7CiAgICAgICAgY2FzZSA3NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgY2FzZSA3ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICBjYXNlIDc5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKTsKICAgICAgICBjYXNlIDgwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICBjYXNlIDgxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgY2FzZSA4MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpOwogICAgICAgIGNhc2UgODM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICBjYXNlIDg0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgY2FzZSA4NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpOwogICAgICAgIGNhc2UgODY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgY2FzZSA4NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgY2FzZSA4ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpOwogICAgICAgIGNhc2UgODk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgY2FzZSA5MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICBjYXNlIDkxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpOwogICAgICAgIGNhc2UgOTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgIGNhc2UgOTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgIGNhc2UgOTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgICAgIGNhc2UgOTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgY2FzZSA5NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgY2FzZSA5NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCk7CiAgICAgICAgY2FzZSA5ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgIGNhc2UgOTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICBjYXNlIDEwMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKTsKICAgICAgICBjYXNlIDEwMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICBjYXNlIDEwMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCk7CiAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICBjYXNlIDEwNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICBjYXNlIDEwNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCk7CiAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgIGNhc2UgMTA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICBjYXNlIDEwOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpOwogICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICBjYXNlIDExMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCk7CiAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICBjYXNlIDExNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgIGNhc2UgMTE1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpOwogICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgIGNhc2UgMTE3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgIGNhc2UgMTE4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgIGNhc2UgMTIwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgY2FzZSAxMjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCk7CiAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgIGNhc2UgMTIzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgY2FzZSAxMjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKTsKICAgICAgICBjYXNlIDEyNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgIGNhc2UgMTI2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgIGNhc2UgMTI3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpOwogICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgIGNhc2UgMTI5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgY2FzZSAxMzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgY2FzZSAxMzI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgIGNhc2UgMTMzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgY2FzZSAxMzU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgIGNhc2UgMTM2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgIGNhc2UgMTM4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgIGNhc2UgMTM5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgIGNhc2UgMTQxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgY2FzZSAxNDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKTsKICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICBjYXNlIDE0NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICBjYXNlIDE0NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKTsKICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgIGNhc2UgMTQ3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgIGNhc2UgMTQ4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpOwogICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICBjYXNlIDE1MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgY2FzZSAxNTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpOwogICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICBjYXNlIDE1MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgY2FzZSAxNTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKTsKICAgICAgICBjYXNlIDE1NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICBjYXNlIDE1NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgY2FzZSAxNTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKTsKICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgIGNhc2UgMTU5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgY2FzZSAxNjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgY2FzZSAxNjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgY2FzZSAxNjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICBjYXNlIDE2NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICBjYXNlIDE2NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCk7CiAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgIGNhc2UgMTY4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICBjYXNlIDE2OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCk7CiAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgIGNhc2UgMTcxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgY2FzZSAxNzI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCk7CiAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgIGNhc2UgMTc0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgY2FzZSAxNzU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgIGNhc2UgMTc3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgIGNhc2UgMTc4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpOwogICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgIGNhc2UgMTgwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgY2FzZSAxODE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCk7CiAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgY2FzZSAxODM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgIGNhc2UgMTg0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKTsKICAgICAgICBjYXNlIDE4NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgY2FzZSAxODY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgIGNhc2UgMTg3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKTsKICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgIGNhc2UgMTg5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgIGNhc2UgMTkwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKTsKICAgICAgICBjYXNlIDE5MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgIGNhc2UgMTkyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgY2FzZSAxOTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKTsKICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICBjYXNlIDE5NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICBjYXNlIDE5NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKTsKICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgIGNhc2UgMTk4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgIGNhc2UgMTk5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpOwogICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICBjYXNlIDIwMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICBjYXNlIDIwNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0JPT0xfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xCb29sMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEJvb2wxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQm9vbDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xCb29sMSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBCb29sQm9vbDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9CWVRFU18yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xCeXRlczJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQnl0ZXMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfRE9VQkxFXzNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sRG91YmxlM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRG91YmxlM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbERvdWJsZTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xEb3VibGUzKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwQm9vbERvdWJsZTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9FTlVNXzRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xFbnVtNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEVudW00XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRW51bTRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwQm9vbEVudW00VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xFbnVtNCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZJWEVEMzJfNV9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sRml4ZWQ2NDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9GTE9BVF83X0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZsb2F0N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9JTlQzMl84X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEludDMyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sSW50NjQ5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDY0OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDY0OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfTUVTU0FHRV8xMF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0ZJWEVEMzJfMTFfRklFTERfTlVNQkVSID0gMTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkNjQxMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1NJTlQzMl8xM19GSUVMRF9OVU1CRVIgPSAxMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xTaW50MzIxM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDMyMTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQzMjEzKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1NJTlQ2NF8xNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDY0MTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50NjQxNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9TVFJJTkdfMTVfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTdHJpbmcxNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1VJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1VJTlQ2NF8xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDY0MTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sVWludDY0MTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDY0MTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCb29sMThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVIgPSAxOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCeXRlczE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9ET1VCTEVfMjBfRklFTERfTlVNQkVSID0gMjA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfRU5VTV8yMV9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9GSVhFRDMyXzIyX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVENjRfMjNfRklFTERfTlVNQkVSID0gMjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZMT0FUXzI0X0ZJRUxEX05VTUJFUiA9IDI0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfSU5UMzJfMjVfRklFTERfTlVNQkVSID0gMjU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJJbnQzMjI1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9JTlQ2NF8yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUiA9IDI3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDMyXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfU0ZJWEVENjRfMjlfRklFTERfTlVNQkVSID0gMjk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfU0lOVDMyXzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TSU5UNjRfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSID0gMzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfVUlOVDMyXzMzX0ZJRUxEX05VTUJFUiA9IDMzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9VSU5UNjRfMzRfRklFTERfTlVNQkVSID0gMzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJVaW50NjQzNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9CT09MXzM1X0ZJRUxEX05VTUJFUiA9IDM1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qm9vbDM1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfQllURVNfMzZfRklFTERfTlVNQkVSID0gMzY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0RPVUJMRV8zN19GSUVMRF9OVU1CRVIgPSAzNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEVudW0zOCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUiA9IDM5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDY0XzQwX0ZJRUxEX05VTUJFUiA9IDQwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfRkxPQVRfNDFfRklFTERfTlVNQkVSID0gNDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRGbG9hdDQxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSID0gNDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50MzI0MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0SW50MzI0Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0SW50MzI0Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDMyNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0SW50MzI0Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfSU5UNjRfNDNfRklFTERfTlVNQkVSID0gNDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50NjQ0M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0SW50NjQ0MygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X01FU1NBR0VfNDRfRklFTERfTlVNQkVSID0gNDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NGSVhFRDMyXzQ1X0ZJRUxEX05VTUJFUiA9IDQ1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NGSVhFRDY0XzQ2X0ZJRUxEX05VTUJFUiA9IDQ2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UMzJfNDdfRklFTERfTlVNQkVSID0gNDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UNjRfNDhfRklFTERfTlVNQkVSID0gNDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfU1RSSU5HXzQ5X0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UMzJfNTBfRklFTERfTlVNQkVSID0gNTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRVaW50MzI1MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0VWludDMyNTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UNjRfNTFfRklFTERfTlVNQkVSID0gNTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDY0NTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0JPT0xfNTJfRklFTERfTlVNQkVSID0gNTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJCb29sNTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0JZVEVTXzUzX0ZJRUxEX05VTUJFUiA9IDUzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkJ5dGVzNTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyQnl0ZXM1M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCeXRlczUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCeXRlczUzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQnl0ZXM1MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0RPVUJMRV81NF9GSUVMRF9OVU1CRVIgPSA1NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJEb3VibGU1NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRG91YmxlNTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEludDMyRG91YmxlNTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyRG91YmxlNTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9FTlVNXzU1X0ZJRUxEX05VTUJFUiA9IDU1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyRW51bTU1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyRW51bTU1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRW51bTU1XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0ZJWEVEMzJfNTZfRklFTERfTlVNQkVSID0gNTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRml4ZWQzMjU2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfRklYRUQ2NF81N19GSUVMRF9OVU1CRVIgPSA1NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQ2NDU3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfRkxPQVRfNThfRklFTERfTlVNQkVSID0gNTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkZsb2F0NThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9JTlQzMl81OV9GSUVMRF9OVU1CRVIgPSA1OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDMyNTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkludDMyNTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMySW50MzI1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0lOVDY0XzYwX0ZJRUxEX05VTUJFUiA9IDYwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50NjQ2MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkludDY0NjBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMySW50NjQ2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50NjQ2MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDY0NjAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX01FU1NBR0VfNjFfRklFTERfTlVNQkVSID0gNjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyTWVzc2FnZTYxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBmaWVsZE1hcEludDMyTWVzc2FnZTYxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyTWVzc2FnZTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVEMzJfNjJfRklFTERfTlVNQkVSID0gNjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TRklYRUQ2NF82M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TSU5UMzJfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1NJTlQ2NF82NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50NjQ2NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1NUUklOR182Nl9GSUVMRF9OVU1CRVIgPSA2NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJTdHJpbmc2NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU3RyaW5nNjZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU3RyaW5nNjZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9VSU5UMzJfNjdfRklFTERfTlVNQkVSID0gNjc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX1VJTlQ2NF82OF9GSUVMRF9OVU1CRVIgPSA2ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50NjQ2OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0JPT0xfNjlfRklFTERfTlVNQkVSID0gNjk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJvb2w2OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRCb29sNjlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qm9vbDY5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9CWVRFU183MF9GSUVMRF9OVU1CRVIgPSA3MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRCeXRlczcwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRE9VQkxFXzcxX0ZJRUxEX05VTUJFUiA9IDcxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEludDY0RG91YmxlNzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0RG91YmxlNzFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RG91YmxlNzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9FTlVNXzcyX0ZJRUxEX05VTUJFUiA9IDcyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEVudW03MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEVudW03Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEVudW03Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03Ml87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEludDY0RW51bTcyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0ZJWEVEMzJfNzNfRklFTERfTlVNQkVSID0gNzM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0ZJWEVENjRfNzRfRklFTERfTlVNQkVSID0gNzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVIgPSA3NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBJbnQ2NEZsb2F0NzVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEZsb2F0NzVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9JTlQzMl83Nl9GSUVMRF9OVU1CRVIgPSA3NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9JTlQ2NF83N19GSUVMRF9OVU1CRVIgPSA3NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0SW50NjQ3N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfTUVTU0FHRV83OF9GSUVMRF9OVU1CRVIgPSA3ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBmaWVsZE1hcEludDY0TWVzc2FnZTc4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVEMzJfNzlfRklFTERfTlVNQkVSID0gNzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVENjRfODBfRklFTERfTlVNQkVSID0gODA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NJTlQzMl84MV9GSUVMRF9OVU1CRVIgPSA4MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NJTlQ2NF84Ml9GSUVMRF9OVU1CRVIgPSA4MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50NjQ4MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TVFJJTkdfODNfRklFTERfTlVNQkVSID0gODM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0U3RyaW5nODNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1VJTlQzMl84NF9GSUVMRF9OVU1CRVIgPSA4NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQzMjg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1VJTlQ2NF84NV9GSUVMRF9OVU1CRVIgPSA4NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50NjQ4NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50NjQ4NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDY0ODVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0VWludDY0ODUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9CT09MXzg2X0ZJRUxEX05VTUJFUiA9IDg2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkJvb2w4NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9CWVRFU184N19GSUVMRF9OVU1CRVIgPSA4NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9ET1VCTEVfODhfRklFTERfTlVNQkVSID0gODg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRU5VTV84OV9GSUVMRF9OVU1CRVIgPSA4OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gZmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9GSVhFRDMyXzkwX0ZJRUxEX05VTUJFUiA9IDkwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0ZJWEVENjRfOTFfRklFTERfTlVNQkVSID0gOTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0ZMT0FUXzkyX0ZJRUxEX05VTUJFUiA9IDkyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfSU5UMzJfOTNfRklFTERfTlVNQkVSID0gOTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9JTlQ2NF85NF9GSUVMRF9OVU1CRVIgPSA5NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9NRVNTQUdFXzk1X0ZJRUxEX05VTUJFUiA9IDk1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX1NGSVhFRDMyXzk2X0ZJRUxEX05VTUJFUiA9IDk2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0ZJWEVENjRfOTdfRklFTERfTlVNQkVSID0gOTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDMyXzk4X0ZJRUxEX05VTUJFUiA9IDk4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TSU5UNjRfOTlfRklFTERfTlVNQkVSID0gOTk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TVFJJTkdfMTAwX0ZJRUxEX05VTUJFUiA9IDEwMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfVUlOVDMyXzEwMV9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9VSU5UNjRfMTAyX0ZJRUxEX05VTUJFUiA9IDEwMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9CT09MXzEwM19GSUVMRF9OVU1CRVIgPSAxMDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfQllURVNfMTA0X0ZJRUxEX05VTUJFUiA9IDEwNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X0RPVUJMRV8xMDVfRklFTERfTlVNQkVSID0gMTA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfRU5VTV8xMDZfRklFTERfTlVNQkVSID0gMTA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDMyXzEwN19GSUVMRF9OVU1CRVIgPSAxMDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVIgPSAxMDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfRkxPQVRfMTA5X0ZJRUxEX05VTUJFUiA9IDEwOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UMzJfMTEwX0ZJRUxEX05VTUJFUiA9IDExMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUiA9IDExMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X01FU1NBR0VfMTEyX0ZJRUxEX05VTUJFUiA9IDExMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDMyXzExM19GSUVMRF9OVU1CRVIgPSAxMTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDY0XzExNF9GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UMzJfMTE1X0ZJRUxEX05VTUJFUiA9IDExNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UNjRfMTE2X0ZJRUxEX05VTUJFUiA9IDExNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfU1RSSU5HXzExN19GSUVMRF9OVU1CRVIgPSAxMTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UMzJfMTE4X0ZJRUxEX05VTUJFUiA9IDExODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UNjRfMTE5X0ZJRUxEX05VTUJFUiA9IDExOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUiA9IDEyMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJvb2wxMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVIgPSAxMjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0RPVUJMRV8xMjJfRklFTERfTlVNQkVSID0gMTIyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9FTlVNXzEyM19GSUVMRF9OVU1CRVIgPSAxMjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRW51bTEyM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0ZJWEVEMzJfMTI0X0ZJRUxEX05VTUJFUiA9IDEyNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRklYRUQ2NF8xMjVfRklFTERfTlVNQkVSID0gMTI1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRkxPQVRfMTI2X0ZJRUxEX05VTUJFUiA9IDEyNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGbG9hdDEyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9JTlQzMl8xMjdfRklFTERfTlVNQkVSID0gMTI3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDMyMTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0lOVDY0XzEyOF9GSUVMRF9OVU1CRVIgPSAxMjg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUiA9IDEyOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVEMzJfMTMwX0ZJRUxEX05VTUJFUiA9IDEzMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9TRklYRUQ2NF8xMzFfRklFTERfTlVNQkVSID0gMTMxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9TSU5UMzJfMTMyX0ZJRUxEX05VTUJFUiA9IDEzMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NJTlQ2NF8xMzNfRklFTERfTlVNQkVSID0gMTMzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSID0gMTM0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9VSU5UMzJfMTM1X0ZJRUxEX05VTUJFUiA9IDEzNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1VJTlQ2NF8xMzZfRklFTERfTlVNQkVSID0gMTM2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0JPT0xfMTM3X0ZJRUxEX05VTUJFUiA9IDEzNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRCb29sMTM3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCb29sMTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qm9vbDEzN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9CWVRFU18xMzhfRklFTERfTlVNQkVSID0gMTM4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRCeXRlczEzOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCeXRlczEzOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfRE9VQkxFXzEzOV9GSUVMRF9OVU1CRVIgPSAxMzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVIgPSAxNDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUiA9IDE0MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVENjRfMTQyX0ZJRUxEX05VTUJFUiA9IDE0MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9GTE9BVF8xNDNfRklFTERfTlVNQkVSID0gMTQzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSID0gMTQ0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRJbnQzMjE0NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRJbnQzMjE0NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50MzIxNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRJbnQzMjE0NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9JTlQ2NF8xNDVfRklFTERfTlVNQkVSID0gMTQ1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfTUVTU0FHRV8xNDZfRklFTERfTlVNQkVSID0gMTQ2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU0ZJWEVEMzJfMTQ3X0ZJRUxEX05VTUJFUiA9IDE0NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU0ZJWEVENjRfMTQ4X0ZJRUxEX05VTUJFUiA9IDE0ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NJTlQzMl8xNDlfRklFTERfTlVNQkVSID0gMTQ5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRTaW50MzIxNDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NJTlQ2NF8xNTBfRklFTERfTlVNQkVSID0gMTUwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9TVFJJTkdfMTUxX0ZJRUxEX05VTUJFUiA9IDE1MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1VJTlQzMl8xNTJfRklFTERfTlVNQkVSID0gMTUyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1VJTlQ2NF8xNTNfRklFTERfTlVNQkVSID0gMTUzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0VWludDY0MTUzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19CT09MXzE1NF9GSUVMRF9OVU1CRVIgPSAxNTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdCb29sMTU0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0JZVEVTXzE1NV9GSUVMRF9OVU1CRVIgPSAxNTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0J5dGVzMTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRE9VQkxFXzE1Nl9GSUVMRF9OVU1CRVIgPSAxNTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRU5VTV8xNTdfRklFTERfTlVNQkVSID0gMTU3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRW51bTE1N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0VudW0xNTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0VudW0xNTdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19GSVhFRDMyXzE1OF9GSUVMRF9OVU1CRVIgPSAxNTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRklYRUQ2NF8xNTlfRklFTERfTlVNQkVSID0gMTU5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19GTE9BVF8xNjBfRklFTERfTlVNQkVSID0gMTYwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfSU5UMzJfMTYxX0ZJRUxEX05VTUJFUiA9IDE2MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0lOVDY0XzE2Ml9GSUVMRF9OVU1CRVIgPSAxNjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ludDY0MTYyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50NjQxNjIoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfTUVTU0FHRV8xNjNfRklFTERfTlVNQkVSID0gMTYzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NGSVhFRDMyXzE2NF9GSUVMRF9OVU1CRVIgPSAxNjQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSID0gMTY1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NJTlQzMl8xNjZfRklFTERfTlVNQkVSID0gMTY2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TSU5UNjRfMTY3X0ZJRUxEX05VTUJFUiA9IDE2NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NUUklOR18xNjhfRklFTERfTlVNQkVSID0gMTY4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1VJTlQzMl8xNjlfRklFTERfTlVNQkVSID0gMTY5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19VSU5UNjRfMTcwX0ZJRUxEX05VTUJFUiA9IDE3MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nVWludDY0MTcwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUiA9IDE3MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVIgPSAxNzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBVaW50MzJCeXRlczE3Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0RPVUJMRV8xNzNfRklFTERfTlVNQkVSID0gMTczOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRG91YmxlMTczXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRG91YmxlMTczKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9FTlVNXzE3NF9GSUVMRF9OVU1CRVIgPSAxNzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRW51bTE3NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0ZJWEVEMzJfMTc1X0ZJRUxEX05VTUJFUiA9IDE3NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRklYRUQ2NF8xNzZfRklFTERfTlVNQkVSID0gMTc2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRkxPQVRfMTc3X0ZJRUxEX05VTUJFUiA9IDE3NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9JTlQzMl8xNzhfRklFTERfTlVNQkVSID0gMTc4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0lOVDY0XzE3OV9GSUVMRF9OVU1CRVIgPSAxNzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUiA9IDE4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVEMzJfMTgxX0ZJRUxEX05VTUJFUiA9IDE4MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9TRklYRUQ2NF8xODJfRklFTERfTlVNQkVSID0gMTgyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9TSU5UMzJfMTgzX0ZJRUxEX05VTUJFUiA9IDE4MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NJTlQ2NF8xODRfRklFTERfTlVNQkVSID0gMTg0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSID0gMTg1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTdHJpbmcxODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9VSU5UMzJfMTg2X0ZJRUxEX05VTUJFUiA9IDE4NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDMyMTg2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1VJTlQ2NF8xODdfRklFTERfTlVNQkVSID0gMTg3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDY0MTg3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0JPT0xfMTg4X0ZJRUxEX05VTUJFUiA9IDE4ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRCb29sMTg4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qm9vbDE4OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9CWVRFU18xODlfRklFTERfTlVNQkVSID0gMTg5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfRE9VQkxFXzE5MF9GSUVMRF9OVU1CRVIgPSAxOTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVIgPSAxOTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUiA9IDE5MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVENjRfMTkzX0ZJRUxEX05VTUJFUiA9IDE5MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9GTE9BVF8xOTRfRklFTERfTlVNQkVSID0gMTk0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSID0gMTk1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9JTlQ2NF8xOTZfRklFTERfTlVNQkVSID0gMTk2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRJbnQ2NDE5NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0SW50NjQxOTZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0SW50NjQxOTZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0SW50NjQxOTZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfTUVTU0FHRV8xOTdfRklFTERfTlVNQkVSID0gMTk3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU0ZJWEVEMzJfMTk4X0ZJRUxEX05VTUJFUiA9IDE5ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU0ZJWEVENjRfMTk5X0ZJRUxEX05VTUJFUiA9IDE5OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NJTlQzMl8yMDBfRklFTERfTlVNQkVSID0gMjAwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRTaW50MzIyMDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NJTlQ2NF8yMDFfRklFTERfTlVNQkVSID0gMjAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRTaW50NjQyMDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ludDY0MjAxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9TVFJJTkdfMjAyX0ZJRUxEX05VTUJFUiA9IDIwMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1VJTlQzMl8yMDNfRklFTERfTlVNQkVSID0gMjAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRVaW50MzIyMDNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1VJTlQ2NF8yMDRfRklFTERfTlVNQkVSID0gMjA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLAogICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLAogICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLAogICAgICAgICAgRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLAogICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLAogICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGbG9hdDQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDU5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLAogICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLAogICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDY2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTAwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTU4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTY3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTczKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxODApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTg4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBmaWVsZE1hcEJvb2xCb29sMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXyA9IEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZmllbGRNYXBCb29sQnl0ZXMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfXyA9IEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGZpZWxkTWFwQm9vbERvdWJsZTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sRW51bTRfXyA9IEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBmaWVsZE1hcEJvb2xFbnVtNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fID0gRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18gPSBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgZmllbGRNYXBCb29sRml4ZWQ2NDZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3X18gPSBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGZpZWxkTWFwQm9vbEZsb2F0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sSW50MzI4X18gPSBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIGZpZWxkTWFwQm9vbEludDMyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18gPSBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGZpZWxkTWFwQm9vbEludDY0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fID0gRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZmllbGRNYXBCb29sTWVzc2FnZTEwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV9fID0gRmllbGRNYXBCb29sU2ZpeGVkMzIxMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEsIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyX18gPSBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMiwgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM19fID0gRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzLCBmaWVsZE1hcEJvb2xTaW50MzIxM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF9fID0gRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0LCBmaWVsZE1hcEJvb2xTaW50NjQxNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBCb29sU3RyaW5nMTVfXyA9IEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNSwgZmllbGRNYXBCb29sU3RyaW5nMTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sVWludDMyMTZfXyA9IEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgZmllbGRNYXBCb29sVWludDMyMTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfXyA9IEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNywgZmllbGRNYXBCb29sVWludDY0MTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fID0gRmllbGRNYXBGaXhlZDMyQm9vbDE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOCwgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5X18gPSBGaWVsZE1hcEZpeGVkMzJCeXRlczE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOSwgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXyA9IEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMCwgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fID0gRmllbGRNYXBGaXhlZDMyRW51bTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMSwgZmllbGRNYXBGaXhlZDMyRW51bTIxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXyA9IEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjIsIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18gPSBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIzLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfXyA9IEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI0LCBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMySW50MzIyNV9fID0gRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjUsIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2X18gPSBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNiwgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN19fID0gRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNywgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fID0gRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjgsIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18gPSBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyOSwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fID0gRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMwLCBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fID0gRmllbGRNYXBGaXhlZDMyU2ludDY0MzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMxLCBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXyA9IEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzMiwgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXyA9IEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzMywgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXyA9IEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNCwgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fID0gRmllbGRNYXBGaXhlZDY0Qm9vbDM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNSwgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18gPSBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNiwgZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXyA9IEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNywgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF9fID0gRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzOCwgZmllbGRNYXBGaXhlZDY0RW51bTM4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXyA9IEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMzksIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwX18gPSBGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQwLCBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXyA9IEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQxLCBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fID0gRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDIsIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18gPSBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0MywgZmllbGRNYXBGaXhlZDY0SW50NjQ0M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fID0gRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NCwgZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fID0gRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDUsIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18gPSBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NiwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fID0gRmllbGRNYXBGaXhlZDY0U2ludDMyNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ3LCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fID0gRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ4LCBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyA9IEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MCwgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MSwgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEludDMyQm9vbDUyX18gPSBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MiwgZmllbGRNYXBJbnQzMkJvb2w1Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTMsIGZpZWxkTWFwSW50MzJCeXRlczUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18gPSBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU0LCBmaWVsZE1hcEludDMyRG91YmxlNTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyRW51bTU1X18gPSBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1NSwgZmllbGRNYXBJbnQzMkVudW01NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXyA9IEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU2LCBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fID0gRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTcsIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF9fID0gRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU4LCBmaWVsZE1hcEludDMyRmxvYXQ1OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fID0gRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU5LCBmaWVsZE1hcEludDMySW50MzI1OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF9fID0gRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYwLCBmaWVsZE1hcEludDMySW50NjQ2MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICBmaWVsZE1hcEludDMyTWVzc2FnZTYxX18gPSBGaWVsZE1hcEludDMyTWVzc2FnZTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MSwgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fID0gRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYyLCBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fID0gRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYzLCBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18gPSBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY0LCBmaWVsZE1hcEludDMyU2ludDMyNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fID0gRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NSwgZmllbGRNYXBJbnQzMlNpbnQ2NDY1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2X18gPSBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY2LCBmaWVsZE1hcEludDMyU3RyaW5nNjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N19fID0gRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NywgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfXyA9IEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjgsIGZpZWxkTWFwSW50MzJVaW50NjQ2OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfXyA9IEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY5LCBmaWVsZE1hcEludDY0Qm9vbDY5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXyA9IEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3MCwgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfXyA9IEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzEsIGZpZWxkTWFwSW50NjREb3VibGU3MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRFbnVtNzJfXyA9IEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcyLCBmaWVsZE1hcEludDY0RW51bTcyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M19fID0gRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzMsIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0X18gPSBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3NCwgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1X18gPSBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzUsIGZpZWxkTWFwSW50NjRGbG9hdDc1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2X18gPSBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzYsIGZpZWxkTWFwSW50NjRJbnQzMjc2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18gPSBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzcsIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXyA9IEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc4LCBmaWVsZE1hcEludDY0TWVzc2FnZTc4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18gPSBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzksIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18gPSBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODAsIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfXyA9IEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODEsIGZpZWxkTWFwSW50NjRTaW50MzI4MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18gPSBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgyLCBmaWVsZE1hcEludDY0U2ludDY0ODJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfXyA9IEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODMsIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQzMjg0X18gPSBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg0LCBmaWVsZE1hcEludDY0VWludDMyODRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fID0gRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4NSwgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fID0gRmllbGRNYXBTZml4ZWQzMkJvb2w4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODYsIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fID0gRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg3LCBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fID0gRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4OCwgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fID0gRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODksIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18gPSBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5MCwgZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXyA9IEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkxLCBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXyA9IEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5MiwgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXyA9IEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5MywgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXyA9IEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NCwgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fID0gRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTUsIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NiwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NywgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fID0gRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5OCwgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTksIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18gPSBGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDAsIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDEsIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDIsIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXyA9IEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDMsIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fID0gRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDQsIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDUsIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDYsIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18gPSBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTA3LCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fID0gRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOCwgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18gPSBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOSwgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyA9IEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEwLCBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fID0gRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTEsIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXyA9IEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTIsIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEzLCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fID0gRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTQsIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExNSwgZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExNiwgZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18gPSBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTcsIGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18gPSBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTgsIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18gPSBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTksIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fID0gRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjAsIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fID0gRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIxLCBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl9fID0gRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyMiwgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM19fID0gRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjMsIGZpZWxkTWFwU2ludDMyRW51bTEyM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18gPSBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNCwgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXyA9IEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTI1LCBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXyA9IEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNiwgZmllbGRNYXBTaW50MzJGbG9hdDEyNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXyA9IEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNywgZmllbGRNYXBTaW50MzJJbnQzMjEyN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXyA9IEZpZWxkTWFwU2ludDMySW50NjQxMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyOCwgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fID0gRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjksIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfXyA9IEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMCwgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfXyA9IEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMSwgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fID0gRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMiwgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyA9IEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzMsIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fID0gRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzNCwgZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfXyA9IEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzUsIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18gPSBGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM2LCBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTaW50NjRCb29sMTM3X18gPSBGaWVsZE1hcFNpbnQ2NEJvb2wxMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzNywgZmllbGRNYXBTaW50NjRCb29sMTM3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4X18gPSBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzgsIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18gPSBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM5LCBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRFbnVtMTQwX18gPSBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0MCwgZmllbGRNYXBTaW50NjRFbnVtMTQwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXyA9IEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQxLCBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fID0gRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDIsIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M19fID0gRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQzLCBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRJbnQzMjE0NF9fID0gRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ0LCBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRJbnQ2NDE0NV9fID0gRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ1LCBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18gPSBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0NiwgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fID0gRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ3LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fID0gRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ4LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5X18gPSBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ5LCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fID0gRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MCwgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18gPSBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUxLCBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MiwgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfXyA9IEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTMsIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18gPSBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NCwgZmllbGRNYXBTdHJpbmdCb29sMTU0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTU1LCBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfXyA9IEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTYsIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18gPSBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NywgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OCwgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OSwgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fID0gRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTYwLCBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXyA9IEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2MSwgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18gPSBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjIsIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18gPSBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2MywgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXyA9IEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2NCwgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18gPSBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjUsIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18gPSBGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY2LCBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXyA9IEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjcsIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfXyA9IEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjgsIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV9fID0gRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2OSwgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwX18gPSBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcwLCBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxX18gPSBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3MSwgZmllbGRNYXBVaW50MzJCb29sMTcxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18gPSBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzIsIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwVWludDMyRG91YmxlMTczX18gPSBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTczLCBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0X18gPSBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3NCwgZmllbGRNYXBVaW50MzJFbnVtMTc0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXyA9IEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc1LCBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fID0gRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzYsIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fID0gRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc3LCBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fID0gRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc4LCBmaWVsZE1hcFVpbnQzMkludDMyMTc4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fID0gRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc5LCBmaWVsZE1hcFVpbnQzMkludDY0MTc5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18gPSBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4MCwgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV9fID0gRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgxLCBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml9fID0gRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgyLCBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18gPSBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgzLCBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF9fID0gRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4NCwgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1X18gPSBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg1LCBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fID0gRmllbGRNYXBVaW50MzJVaW50MzIxODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4NiwgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyA9IEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODcsIGZpZWxkTWFwVWludDMyVWludDY0MTg3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXyA9IEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg4LCBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfXyA9IEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4OSwgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyA9IEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTAsIGZpZWxkTWFwVWludDY0RG91YmxlMTkwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXyA9IEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTkxLCBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fID0gRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTIsIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18gPSBGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5MywgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0X18gPSBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTQsIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDMyMTk1X18gPSBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTUsIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDY0MTk2X18gPSBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTYsIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyA9IEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTk3LCBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTgsIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXyA9IEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDAsIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAxLCBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDIsIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzX18gPSBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAzLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fID0gRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNCwgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQk9PTF8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQllURVNfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRE9VQkxFXzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRU5VTV80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9GSVhFRDMyXzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZMT0FUXzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfSU5UMzJfOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NGSVhFRDMyXzExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0lOVDMyXzEzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9TSU5UNjRfMTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NUUklOR18xNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfVUlOVDMyXzE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9VSU5UNjRfMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9ET1VCTEVfMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9FTlVNXzIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVEMzJfMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRklYRUQ2NF8yM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRkxPQVRfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9JTlQzMl8yNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0lOVDY0XzI2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TRklYRUQzMl8yOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDY0XzI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NJTlQzMl8zMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfU0lOVDY0XzMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1VJTlQzMl8zM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfVUlOVDY0XzM0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQk9PTF8zNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQllURVNfMzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRE9VQkxFXzM3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZJWEVENjRfNDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZMT0FUXzQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9JTlQ2NF80M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfTUVTU0FHRV80NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU0ZJWEVEMzJfNDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQ2NF80Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UMzJfNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1NJTlQ2NF80OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU1RSSU5HXzQ5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UMzJfNTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1VJTlQ2NF81MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQk9PTF81Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQllURVNfNTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRE9VQkxFXzU0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRU5VTV81NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9GSVhFRDMyXzU2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZJWEVENjRfNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZMT0FUXzU4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfSU5UMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9JTlQ2NF82MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfTUVTU0FHRV82MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVEMzJfNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TRklYRUQ2NF82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1NJTlQ2NF82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU1RSSU5HXzY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9VSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1VJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JPT0xfNjlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JZVEVTXzcwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0RPVUJMRV83MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0VOVU1fNzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfRklYRUQzMl83M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GSVhFRDY0Xzc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0lOVDMyXzc2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfSU5UNjRfNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X01FU1NBR0VfNzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NGSVhFRDMyXzc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVENjRfODBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0lOVDMyXzgxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9TSU5UNjRfODJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfVUlOVDMyXzg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9VSU5UNjRfODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CT09MXzg2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CWVRFU184N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9ET1VCTEVfODhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0ZJWEVEMzJfOTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRkxPQVRfOTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9JTlQzMl85M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9NRVNTQUdFXzk1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQzMl85Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NGSVhFRDY0Xzk3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NJTlQzMl85OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDY0Xzk5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU1RSSU5HXzEwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9VSU5UMzJfMTAxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1VJTlQ2NF8xMDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JPT0xfMTAzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JZVEVTXzEwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0RPVUJMRV8xMDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0VOVU1fMTA2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfRklYRUQzMl8xMDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GTE9BVF8xMDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0lOVDMyXzExMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X01FU1NBR0VfMTEyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDMyXzExM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0ZJWEVENjRfMTE0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0lOVDMyXzExNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UNjRfMTE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NUUklOR18xMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfVUlOVDMyXzExOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UNjRfMTE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0RPVUJMRV8xMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0VOVU1fMTIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfRklYRUQzMl8xMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GSVhFRDY0XzEyNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GTE9BVF8xMjZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0lOVDMyXzEyN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfSU5UNjRfMTI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NGSVhFRDMyXzEzMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVENjRfMTMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0lOVDMyXzEzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9TSU5UNjRfMTMzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfVUlOVDMyXzEzNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9VSU5UNjRfMTM2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CT09MXzEzN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CWVRFU18xMzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9ET1VCTEVfMTM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRklYRUQ2NF8xNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRkxPQVRfMTQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0lOVDY0XzE0NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9NRVNTQUdFXzE0Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TRklYRUQzMl8xNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDY0XzE0OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NJTlQzMl8xNDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfU0lOVDY0XzE1MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TVFJJTkdfMTUxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1VJTlQzMl8xNTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfVUlOVDY0XzE1M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQk9PTF8xNTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQllURVNfMTU1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRE9VQkxFXzE1Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRU5VTV8xNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19GSVhFRDMyXzE1OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZJWEVENjRfMTU5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZMT0FUXzE2MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfSU5UMzJfMTYxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19JTlQ2NF8xNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfTUVTU0FHRV8xNjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVEMzJfMTY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TSU5UMzJfMTY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1NJTlQ2NF8xNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU1RSSU5HXzE2OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19VSU5UMzJfMTY5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1VJTlQ2NF8xNzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0RPVUJMRV8xNzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0VOVU1fMTc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfRklYRUQzMl8xNzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GSVhFRDY0XzE3Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GTE9BVF8xNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0lOVDMyXzE3OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfSU5UNjRfMTc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NGSVhFRDMyXzE4MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVENjRfMTgyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0lOVDMyXzE4M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9TSU5UNjRfMTg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfVUlOVDMyXzE4Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9VSU5UNjRfMTg3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CT09MXzE4OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CWVRFU18xODlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9ET1VCTEVfMTkwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRklYRUQ2NF8xOTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRkxPQVRfMTk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0lOVDY0XzE5Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9NRVNTQUdFXzE5N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TRklYRUQzMl8xOThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDY0XzE5OV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NJTlQzMl8yMDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfU0lOVDY0XzIwMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TVFJJTkdfMjAyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1VJTlQzMl8yMDNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfVUlOVDY0XzIwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKTsKICAgICAgICAgIGNhc2UgMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICAgIGNhc2UgMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKTsKICAgICAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgICBjYXNlIDE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKTsKICAgICAgICAgIGNhc2UgMTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgICAgY2FzZSAxODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCk7CiAgICAgICAgICBjYXNlIDE5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAgICAgICBjYXNlIDIwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgICAgY2FzZSAyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCk7CiAgICAgICAgICBjYXNlIDIyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICAgIGNhc2UgMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpOwogICAgICAgICAgY2FzZSAyNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgICAgY2FzZSAyNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgICAgY2FzZSAyNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCk7CiAgICAgICAgICBjYXNlIDI4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCk7CiAgICAgICAgICBjYXNlIDI5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgICBjYXNlIDMwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpOwogICAgICAgICAgY2FzZSAzMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgICBjYXNlIDMzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpOwogICAgICAgICAgY2FzZSAzNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIGNhc2UgMzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgY2FzZSAzNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpOwogICAgICAgICAgY2FzZSAzNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIGNhc2UgMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgY2FzZSAzOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCk7CiAgICAgICAgICBjYXNlIDQwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgICAgICAgIGNhc2UgNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICAgIGNhc2UgNDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKTsKICAgICAgICAgIGNhc2UgNDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKTsKICAgICAgICAgIGNhc2UgNDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgICAgY2FzZSA0NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpOwogICAgICAgICAgY2FzZSA0NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgICAgICAgY2FzZSA0NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIGNhc2UgNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCk7CiAgICAgICAgICBjYXNlIDQ5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpOwogICAgICAgICAgY2FzZSA1MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIGNhc2UgNTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCk7CiAgICAgICAgICBjYXNlIDUyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICBjYXNlIDUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgICAgY2FzZSA1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCk7CiAgICAgICAgICBjYXNlIDU1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICBjYXNlIDU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICBjYXNlIDU3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAgICAgICBjYXNlIDU4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgICAgICAgY2FzZSA1OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIGNhc2UgNjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCk7CiAgICAgICAgICBjYXNlIDYxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAgICAgICBjYXNlIDYyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgICAgY2FzZSA2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgICAgICAgIGNhc2UgNjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgY2FzZSA2NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICBjYXNlIDY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKTsKICAgICAgICAgIGNhc2UgNjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgICAgICAgY2FzZSA2ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICBjYXNlIDY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCk7CiAgICAgICAgICBjYXNlIDcwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgY2FzZSA3MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICBjYXNlIDcyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCk7CiAgICAgICAgICBjYXNlIDczOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCk7CiAgICAgICAgICBjYXNlIDc0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgICBjYXNlIDc1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgICAgICAgY2FzZSA3NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKTsKICAgICAgICAgIGNhc2UgNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgICBjYXNlIDc4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCk7CiAgICAgICAgICBjYXNlIDc5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgY2FzZSA4MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICAgIGNhc2UgODE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpOwogICAgICAgICAgY2FzZSA4MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICBjYXNlIDgzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICAgIGNhc2UgODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpOwogICAgICAgICAgY2FzZSA4NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICBjYXNlIDg2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgICBjYXNlIDg3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpOwogICAgICAgICAgY2FzZSA4ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICBjYXNlIDg5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgICBjYXNlIDkwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCk7CiAgICAgICAgICBjYXNlIDkxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAgICAgICBjYXNlIDkyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgY2FzZSA5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKTsKICAgICAgICAgIGNhc2UgOTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCk7CiAgICAgICAgICBjYXNlIDk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgICBjYXNlIDk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpOwogICAgICAgICAgY2FzZSA5NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgICAgICAgIGNhc2UgOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgICAgY2FzZSA5OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCk7CiAgICAgICAgICBjYXNlIDEwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgICAgY2FzZSAxMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCk7CiAgICAgICAgICBjYXNlIDEwMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgICAgICAgIGNhc2UgMTA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICAgIGNhc2UgMTA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCk7CiAgICAgICAgICBjYXNlIDEwNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgICAgICAgIGNhc2UgMTA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgICAgY2FzZSAxMDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCk7CiAgICAgICAgICBjYXNlIDEwOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAgICAgICBjYXNlIDExMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgICBjYXNlIDExMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCk7CiAgICAgICAgICBjYXNlIDExMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKTsKICAgICAgICAgIGNhc2UgMTE1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAgICAgICBjYXNlIDExNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgICAgY2FzZSAxMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKTsKICAgICAgICAgIGNhc2UgMTE4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAgICAgICBjYXNlIDExOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgICAgY2FzZSAxMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpOwogICAgICAgICAgY2FzZSAxMjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgICAgICAgIGNhc2UgMTIyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgICAgY2FzZSAxMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpOwogICAgICAgICAgY2FzZSAxMjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgICAgICAgY2FzZSAxMjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgICAgY2FzZSAxMjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKTsKICAgICAgICAgIGNhc2UgMTI3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAgICAgICBjYXNlIDEyODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgICAgY2FzZSAxMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpOwogICAgICAgICAgY2FzZSAxMzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKTsKICAgICAgICAgIGNhc2UgMTMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICBjYXNlIDEzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKTsKICAgICAgICAgIGNhc2UgMTMzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpOwogICAgICAgICAgY2FzZSAxMzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgICBjYXNlIDEzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKTsKICAgICAgICAgIGNhc2UgMTM2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpOwogICAgICAgICAgY2FzZSAxMzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgY2FzZSAxMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKTsKICAgICAgICAgIGNhc2UgMTM5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpOwogICAgICAgICAgY2FzZSAxNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgY2FzZSAxNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpOwogICAgICAgICAgY2FzZSAxNDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgY2FzZSAxNDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICAgIGNhc2UgMTQ0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCk7CiAgICAgICAgICBjYXNlIDE0NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgICAgICAgY2FzZSAxNDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgICAgY2FzZSAxNDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKTsKICAgICAgICAgIGNhc2UgMTQ4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICBjYXNlIDE0OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIGNhc2UgMTUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpOwogICAgICAgICAgY2FzZSAxNTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAgICAgICBjYXNlIDE1MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIGNhc2UgMTUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpOwogICAgICAgICAgY2FzZSAxNTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgY2FzZSAxNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICAgIGNhc2UgMTU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpOwogICAgICAgICAgY2FzZSAxNTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgY2FzZSAxNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgY2FzZSAxNTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgICAgICAgY2FzZSAxNjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKTsKICAgICAgICAgIGNhc2UgMTYxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgICBjYXNlIDE2MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpOwogICAgICAgICAgY2FzZSAxNjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpOwogICAgICAgICAgY2FzZSAxNjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIGNhc2UgMTY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCk7CiAgICAgICAgICBjYXNlIDE2NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgICAgICAgIGNhc2UgMTY3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgY2FzZSAxNjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCk7CiAgICAgICAgICBjYXNlIDE2OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKTsKICAgICAgICAgIGNhc2UgMTcwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgY2FzZSAxNzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpOwogICAgICAgICAgY2FzZSAxNzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIGNhc2UgMTczOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgY2FzZSAxNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpOwogICAgICAgICAgY2FzZSAxNzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpOwogICAgICAgICAgY2FzZSAxNzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgICAgY2FzZSAxNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKTsKICAgICAgICAgIGNhc2UgMTc4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCk7CiAgICAgICAgICBjYXNlIDE3OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgICAgY2FzZSAxODA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpOwogICAgICAgICAgY2FzZSAxODE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIGNhc2UgMTgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgICBjYXNlIDE4MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKTsKICAgICAgICAgIGNhc2UgMTg0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgY2FzZSAxODU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgICBjYXNlIDE4NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKTsKICAgICAgICAgIGNhc2UgMTg3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgY2FzZSAxODg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgICAgY2FzZSAxODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgICAgICAgIGNhc2UgMTkwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgY2FzZSAxOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgICAgY2FzZSAxOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpOwogICAgICAgICAgY2FzZSAxOTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgICAgICAgY2FzZSAxOTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICAgIGNhc2UgMTk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCk7CiAgICAgICAgICBjYXNlIDE5NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgICAgY2FzZSAxOTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgICAgY2FzZSAxOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKTsKICAgICAgICAgIGNhc2UgMTk5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAgICAgICBjYXNlIDIwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpOwogICAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgICBjYXNlIDIwMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKTsKICAgICAgICAgIGNhc2UgMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCk7CiAgICAgICAgICBjYXNlIDEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgICBjYXNlIDE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKTsKICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKTsKICAgICAgICAgIGNhc2UgMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICAgIGNhc2UgMTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCk7CiAgICAgICAgICBjYXNlIDIwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKTsKICAgICAgICAgIGNhc2UgMjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICAgIGNhc2UgMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICAgIGNhc2UgMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgICBjYXNlIDI1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgICAgY2FzZSAyNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKTsKICAgICAgICAgIGNhc2UgMjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICAgIGNhc2UgMjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCk7CiAgICAgICAgICBjYXNlIDI5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpOwogICAgICAgICAgY2FzZSAzMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgICBjYXNlIDMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpOwogICAgICAgICAgY2FzZSAzMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgICBjYXNlIDM0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIGNhc2UgMzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKTsKICAgICAgICAgIGNhc2UgMzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICBjYXNlIDM3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIGNhc2UgMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKTsKICAgICAgICAgIGNhc2UgMzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICAgIGNhc2UgNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgICAgICAgIGNhc2UgNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAgICAgICBjYXNlIDQyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgICAgY2FzZSA0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKTsKICAgICAgICAgIGNhc2UgNDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKTsKICAgICAgICAgIGNhc2UgNDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICBjYXNlIDQ2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgICAgICAgY2FzZSA0NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCk7CiAgICAgICAgICBjYXNlIDQ4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIGNhc2UgNDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpOwogICAgICAgICAgY2FzZSA1MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCk7CiAgICAgICAgICBjYXNlIDUxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIGNhc2UgNTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICBjYXNlIDUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICAgIGNhc2UgNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICBjYXNlIDU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpOwogICAgICAgICAgY2FzZSA1NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICAgIGNhc2UgNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpOwogICAgICAgICAgY2FzZSA1OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCk7CiAgICAgICAgICBjYXNlIDYwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIGNhc2UgNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAgICAgICBjYXNlIDYyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKTsKICAgICAgICAgIGNhc2UgNjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgICAgY2FzZSA2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgY2FzZSA2NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpOwogICAgICAgICAgY2FzZSA2NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgICAgY2FzZSA2NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgICAgICAgY2FzZSA2ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpOwogICAgICAgICAgY2FzZSA2OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIGNhc2UgNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgY2FzZSA3MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpOwogICAgICAgICAgY2FzZSA3MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIGNhc2UgNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCk7CiAgICAgICAgICBjYXNlIDc0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpOwogICAgICAgICAgY2FzZSA3NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgICBjYXNlIDc2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKTsKICAgICAgICAgIGNhc2UgNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpOwogICAgICAgICAgY2FzZSA3ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICAgIGNhc2UgNzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgY2FzZSA4MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCk7CiAgICAgICAgICBjYXNlIDgxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICBjYXNlIDgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICBjYXNlIDgzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCk7CiAgICAgICAgICBjYXNlIDg0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICBjYXNlIDg1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICBjYXNlIDg2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpOwogICAgICAgICAgY2FzZSA4NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgICBjYXNlIDg4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICBjYXNlIDg5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpOwogICAgICAgICAgY2FzZSA5MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIGNhc2UgOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCk7CiAgICAgICAgICBjYXNlIDkyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKTsKICAgICAgICAgIGNhc2UgOTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgY2FzZSA5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCk7CiAgICAgICAgICBjYXNlIDk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpOwogICAgICAgICAgY2FzZSA5NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgICBjYXNlIDk3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKTsKICAgICAgICAgIGNhc2UgOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKTsKICAgICAgICAgIGNhc2UgOTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICAgIGNhc2UgMTAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgICAgY2FzZSAxMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCk7CiAgICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICAgIGNhc2UgMTAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKTsKICAgICAgICAgIGNhc2UgMTA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCk7CiAgICAgICAgICBjYXNlIDEwNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICAgIGNhc2UgMTA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgICAgICAgIGNhc2UgMTA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKTsKICAgICAgICAgIGNhc2UgMTA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICAgIGNhc2UgMTA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAgICAgICBjYXNlIDExMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpOwogICAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKTsKICAgICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCk7CiAgICAgICAgICBjYXNlIDExNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgICAgY2FzZSAxMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAgICAgICBjYXNlIDExNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKTsKICAgICAgICAgIGNhc2UgMTE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgICAgY2FzZSAxMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCk7CiAgICAgICAgICBjYXNlIDExOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKTsKICAgICAgICAgIGNhc2UgMTIwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgICBjYXNlIDEyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgICAgICAgIGNhc2UgMTIyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKTsKICAgICAgICAgIGNhc2UgMTIzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgICBjYXNlIDEyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgICAgICAgY2FzZSAxMjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKTsKICAgICAgICAgIGNhc2UgMTI2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgICAgY2FzZSAxMjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCk7CiAgICAgICAgICBjYXNlIDEyODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKTsKICAgICAgICAgIGNhc2UgMTI5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgICBjYXNlIDEzMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKTsKICAgICAgICAgIGNhc2UgMTMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpOwogICAgICAgICAgY2FzZSAxMzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgICAgY2FzZSAxMzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpOwogICAgICAgICAgY2FzZSAxMzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpOwogICAgICAgICAgY2FzZSAxMzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgICAgY2FzZSAxMzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpOwogICAgICAgICAgY2FzZSAxMzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKTsKICAgICAgICAgIGNhc2UgMTM4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgICAgY2FzZSAxMzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpOwogICAgICAgICAgY2FzZSAxNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKTsKICAgICAgICAgIGNhc2UgMTQxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgICBjYXNlIDE0MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgY2FzZSAxNDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCk7CiAgICAgICAgICBjYXNlIDE0NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICAgIGNhc2UgMTQ1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgICAgICAgY2FzZSAxNDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKTsKICAgICAgICAgIGNhc2UgMTQ3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgICAgY2FzZSAxNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICBjYXNlIDE0OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCk7CiAgICAgICAgICBjYXNlIDE1MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgICBjYXNlIDE1MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAgICAgICBjYXNlIDE1MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCk7CiAgICAgICAgICBjYXNlIDE1MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgICBjYXNlIDE1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgY2FzZSAxNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCk7CiAgICAgICAgICBjYXNlIDE1NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgICBjYXNlIDE1NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgY2FzZSAxNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKTsKICAgICAgICAgIGNhc2UgMTU5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgICBjYXNlIDE2MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKTsKICAgICAgICAgIGNhc2UgMTYxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpOwogICAgICAgICAgY2FzZSAxNjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgICBjYXNlIDE2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpOwogICAgICAgICAgY2FzZSAxNjQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCk7CiAgICAgICAgICBjYXNlIDE2NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIGNhc2UgMTY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgICAgICAgIGNhc2UgMTY3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKTsKICAgICAgICAgIGNhc2UgMTY4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICAgIGNhc2UgMTY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKTsKICAgICAgICAgIGNhc2UgMTcwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKTsKICAgICAgICAgIGNhc2UgMTcxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICBjYXNlIDE3MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIGNhc2UgMTczOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKTsKICAgICAgICAgIGNhc2UgMTc0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICBjYXNlIDE3NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpOwogICAgICAgICAgY2FzZSAxNzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKTsKICAgICAgICAgIGNhc2UgMTc3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgICAgY2FzZSAxNzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCk7CiAgICAgICAgICBjYXNlIDE3OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgICAgICAgIGNhc2UgMTgwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgICBjYXNlIDE4MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIGNhc2UgMTgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpOwogICAgICAgICAgY2FzZSAxODM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgY2FzZSAxODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgY2FzZSAxODU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgICAgICAgY2FzZSAxODY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgY2FzZSAxODc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgY2FzZSAxODg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKTsKICAgICAgICAgIGNhc2UgMTg5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgICAgY2FzZSAxOTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgY2FzZSAxOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKTsKICAgICAgICAgIGNhc2UgMTkyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICBjYXNlIDE5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpOwogICAgICAgICAgY2FzZSAxOTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCk7CiAgICAgICAgICBjYXNlIDE5NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICAgIGNhc2UgMTk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgICAgY2FzZSAxOTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKTsKICAgICAgICAgIGNhc2UgMTk4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgICAgY2FzZSAxOTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCk7CiAgICAgICAgICBjYXNlIDIwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCk7CiAgICAgICAgICBjYXNlIDIwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgICBjYXNlIDIwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgICBjYXNlIDIwMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCk7CiAgICAgICAgICBjYXNlIDIwNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgYml0RmllbGQyXyA9IDA7CiAgICAgICAgYml0RmllbGQzXyA9IDA7CiAgICAgICAgYml0RmllbGQ0XyA9IDA7CiAgICAgICAgYml0RmllbGQ1XyA9IDA7CiAgICAgICAgYml0RmllbGQ2XyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMShyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMl8gIT0gMCkgeyBidWlsZFBhcnRpYWwyKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQzXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDMocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDRfICE9IDApIHsgYnVpbGRQYXJ0aWFsNChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkNV8gIT0gMCkgeyBidWlsZFBhcnRpYWw1KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQ2XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDYocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCb29sMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sQm9vbDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCeXRlczJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xCeXRlczJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xEb3VibGUzXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbERvdWJsZTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xFbnVtNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRW51bTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGaXhlZDMyNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRml4ZWQzMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGaXhlZDY0Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRml4ZWQ2NDZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGbG9hdDdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xGbG9hdDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQzMjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQzMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQ2NDlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xJbnQ2NDlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xNZXNzYWdlMTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5idWlsZChGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTZml4ZWQzMjExXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTZml4ZWQ2NDEyXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTaW50MzIxM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ludDMyMTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTaW50NjQxNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ludDY0MTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTdHJpbmcxNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU3RyaW5nMTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xVaW50MzIxNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sVWludDMyMTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xVaW50NjQxN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sVWludDY0MTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCb29sMThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCb29sMThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJEb3VibGUyMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJFbnVtMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkludDMyMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkludDY0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5idWlsZChGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50MzIzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50NjQzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjREb3VibGUzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEVudW0zOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDMyNDJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0SW50MzI0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDY0NDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0SW50NjQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmJ1aWxkKEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50MzI0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50MzI1MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCb29sNTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkJvb2w1Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCeXRlczUzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyQnl0ZXM1M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJEb3VibGU1NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJFbnVtNTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkVudW01NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGbG9hdDU4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRmxvYXQ1OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJJbnQzMjU5XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50MzI1OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50NjQ2MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuYnVpbGQoRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkNjQ2M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTaW50MzI2NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTaW50MzI2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMl8gPSBiaXRGaWVsZDJfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlNpbnQ2NDY1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlN0cmluZzY2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQzMjY3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMlVpbnQ2NDY4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJvb2w2OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Qm9vbDY5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRCeXRlczcwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NERvdWJsZTcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEVudW03Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RW51bTcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQzMjczXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQ2NDc0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRGbG9hdDc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDMyNzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRJbnQzMjc2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDY0NzdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRJbnQ2NDc3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5idWlsZChGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQzMjgxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFN0cmluZzgzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQzMjg0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFVpbnQ2NDg1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRW51bTg5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5idWlsZChGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQzXyA9IGJpdEZpZWxkM187CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDMyOThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuYnVpbGQoRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0VWludDMyMTE4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJvb2wxMjBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJvb2wxMjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJEb3VibGUxMjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkVudW0xMjNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkVudW0xMjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRmxvYXQxMjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkludDMyMTI3XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMySW50MzIxMjdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkludDY0MTI4XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMySW50NjQxMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWw0KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDRfID0gYml0RmllbGQ0XzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmJ1aWxkKEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlN0cmluZzEzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qm9vbDEzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRCeXRlczEzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RW51bTE0MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RW51bTE0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RmxvYXQxNDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRGbG9hdDE0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRJbnQzMjE0NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmJ1aWxkKEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQm9vbDE1NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdCeXRlczE1NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRW51bTE1N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRW51bTE1N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDUoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNV8gPSBiaXRGaWVsZDVfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDMyMTYxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDY0MTYyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuYnVpbGQoRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCb29sMTcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkJ5dGVzMTcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyRG91YmxlMTczXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJFbnVtMTc0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZsb2F0MTc3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDMyMTc4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDY0MTc5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuYnVpbGQoRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50MzIxODNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ludDMyMTgzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50NjQxODRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ludDY0MTg0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU3RyaW5nMTg1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50MzIxODZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyVWludDMyMTg2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50NjQxODdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyVWludDY0MTg3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCb29sMTg4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjREb3VibGUxOTBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0RG91YmxlMTkwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRFbnVtMTkxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsNihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQ2XyA9IGJpdEZpZWxkNl87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0RmxvYXQxOTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEludDMyMTk1XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0SW50MzIxOTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEludDY0MTk2XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0SW50NjQxOTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5idWlsZChGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTaW50MzIyMDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTaW50NjQyMDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRVaW50MzIyMDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRVaW50NjQyMDRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCb29sMV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xCb29sMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sQnl0ZXMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sQnl0ZXMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRG91YmxlM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xEb3VibGUzX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbERvdWJsZTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRW51bTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xFbnVtNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQ2NDZfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sRml4ZWQ2NDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEZsb2F0N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQzMjhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEludDMyOF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xJbnQzMjhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQ2NDlfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sSW50NjQ5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sTWVzc2FnZTEwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xNZXNzYWdlMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sTWVzc2FnZTEwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTZml4ZWQzMjExX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQzMjEzX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFNpbnQzMjEzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ludDY0MTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTaW50NjQxNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICAgIGNhc2UgMTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU3RyaW5nMTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTdHJpbmcxNV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xTdHJpbmcxNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMgogICAgICAgICAgICAgIGNhc2UgMTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sVWludDMyMTZfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sVWludDMyMTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgICBjYXNlIDEzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50NjQxN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDY0MTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM4CiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyQm9vbDE4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJCeXRlczE5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYyCiAgICAgICAgICAgICAgY2FzZSAxNzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRW51bTIxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRW51bTIxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTcwCiAgICAgICAgICAgICAgY2FzZSAxNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZsb2F0MjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50MzIyNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDIKICAgICAgICAgICAgICBjYXNlIDIxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGNhc2UgMjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjE4CiAgICAgICAgICAgICAgY2FzZSAyMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMjYKICAgICAgICAgICAgICBjYXNlIDIzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIzNAogICAgICAgICAgICAgIGNhc2UgMjQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNDIKICAgICAgICAgICAgICBjYXNlIDI1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDY0MzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjUwCiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU4CiAgICAgICAgICAgICAgY2FzZSAyNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NgogICAgICAgICAgICAgIGNhc2UgMjc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50NjQzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzQKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCb29sMzVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRCb29sMzVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODIKICAgICAgICAgICAgICBjYXNlIDI5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTAKICAgICAgICAgICAgICBjYXNlIDI5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjREb3VibGUzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTgKICAgICAgICAgICAgICBjYXNlIDMwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDYKICAgICAgICAgICAgICBjYXNlIDMxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMTQKICAgICAgICAgICAgICBjYXNlIDMyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjIKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzAKICAgICAgICAgICAgICBjYXNlIDMzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50NjQ0M19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ2CiAgICAgICAgICAgICAgY2FzZSAzNTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTQKICAgICAgICAgICAgICBjYXNlIDM2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2MgogICAgICAgICAgICAgIGNhc2UgMzcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzcwCiAgICAgICAgICAgICAgY2FzZSAzNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3OAogICAgICAgICAgICAgIGNhc2UgMzg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzODYKICAgICAgICAgICAgICBjYXNlIDM5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzOTQKICAgICAgICAgICAgICBjYXNlIDQwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxMAogICAgICAgICAgICAgIGNhc2UgNDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCb29sNTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyQm9vbDUyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE4CiAgICAgICAgICAgICAgY2FzZSA0MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkJ5dGVzNTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MjYKICAgICAgICAgICAgICBjYXNlIDQzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkRvdWJsZTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQzNAogICAgICAgICAgICAgIGNhc2UgNDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkVudW01NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRW51bTU1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDQyCiAgICAgICAgICAgICAgY2FzZSA0NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NTAKICAgICAgICAgICAgICBjYXNlIDQ1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQ2NDU3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1OAogICAgICAgICAgICAgIGNhc2UgNDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGbG9hdDU4X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJGbG9hdDU4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDY2CiAgICAgICAgICAgICAgY2FzZSA0NzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkludDMyNTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMySW50MzI1OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ3NAogICAgICAgICAgICAgIGNhc2UgNDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQ2NDYwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMySW50NjQ2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkludDY0NjBfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkludDY0NjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0ODIKICAgICAgICAgICAgICBjYXNlIDQ5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyTWVzc2FnZTYxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDkwCiAgICAgICAgICAgICAgY2FzZSA0OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ5OAogICAgICAgICAgICAgIGNhc2UgNTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MDYKICAgICAgICAgICAgICBjYXNlIDUxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDMyNjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyU2ludDMyNjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTQKICAgICAgICAgICAgICBjYXNlIDUyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDY0NjVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyU2ludDY0NjVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjIKICAgICAgICAgICAgICBjYXNlIDUzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUzMAogICAgICAgICAgICAgIGNhc2UgNTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50MzI2N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJVaW50MzI2N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUzOAogICAgICAgICAgICAgIGNhc2UgNTQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50NjQ2OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJVaW50NjQ2OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU0NgogICAgICAgICAgICAgIGNhc2UgNTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRCb29sNjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEJvb2w2OV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0Qm9vbDY5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTU0CiAgICAgICAgICAgICAgY2FzZSA1NjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRCeXRlczcwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NjIKICAgICAgICAgICAgICBjYXNlIDU3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjREb3VibGU3MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjREb3VibGU3MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU3MAogICAgICAgICAgICAgIGNhc2UgNTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRFbnVtNzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEVudW03Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0RW51bTcyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTc4CiAgICAgICAgICAgICAgY2FzZSA1ODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQzMjczX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1ODYKICAgICAgICAgICAgICBjYXNlIDU5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU5NAogICAgICAgICAgICAgIGNhc2UgNjAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RmxvYXQ3NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRGbG9hdDc1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjAyCiAgICAgICAgICAgICAgY2FzZSA2MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEludDMyNzZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0SW50MzI3Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYxMAogICAgICAgICAgICAgIGNhc2UgNjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQ2NDc3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEludDY0NzdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MTgKICAgICAgICAgICAgICBjYXNlIDYyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0TWVzc2FnZTc4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjI2CiAgICAgICAgICAgICAgY2FzZSA2MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYzNAogICAgICAgICAgICAgIGNhc2UgNjQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NDIKICAgICAgICAgICAgICBjYXNlIDY1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50MzI4MV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0U2ludDMyODFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NTAKICAgICAgICAgICAgICBjYXNlIDY1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0U2ludDY0ODJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NTgKICAgICAgICAgICAgICBjYXNlIDY2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFN0cmluZzgzX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2NgogICAgICAgICAgICAgIGNhc2UgNjc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQzMjg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQzMjg0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY3NAogICAgICAgICAgICAgIGNhc2UgNjgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY4MgogICAgICAgICAgICAgIGNhc2UgNjkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjkwCiAgICAgICAgICAgICAgY2FzZSA2OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2OTgKICAgICAgICAgICAgICBjYXNlIDcwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcwNgogICAgICAgICAgICAgIGNhc2UgNzE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRW51bTg5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzE0CiAgICAgICAgICAgICAgY2FzZSA3MjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjIKICAgICAgICAgICAgICBjYXNlIDczMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczMAogICAgICAgICAgICAgIGNhc2UgNzM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM4CiAgICAgICAgICAgICAgY2FzZSA3NDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NgogICAgICAgICAgICAgIGNhc2UgNzU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkludDY0OTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NTQKICAgICAgICAgICAgICBjYXNlIDc2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYyCiAgICAgICAgICAgICAgY2FzZSA3NzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MAogICAgICAgICAgICAgIGNhc2UgNzc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODYKICAgICAgICAgICAgICBjYXNlIDc5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTQKICAgICAgICAgICAgICBjYXNlIDgwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAyCiAgICAgICAgICAgICAgY2FzZSA4MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTAKICAgICAgICAgICAgICBjYXNlIDgxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgODI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBjYXNlIDgzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODM0CiAgICAgICAgICAgICAgY2FzZSA4NDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg0MgogICAgICAgICAgICAgIGNhc2UgODUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NTAKICAgICAgICAgICAgICBjYXNlIDg1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODU4CiAgICAgICAgICAgICAgY2FzZSA4NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg2NgogICAgICAgICAgICAgIGNhc2UgODc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NzQKICAgICAgICAgICAgICBjYXNlIDg4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4ODIKICAgICAgICAgICAgICBjYXNlIDg5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTAKICAgICAgICAgICAgICBjYXNlIDg5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTgKICAgICAgICAgICAgICBjYXNlIDkwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MDYKICAgICAgICAgICAgICBjYXNlIDkxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MTQKICAgICAgICAgICAgICBjYXNlIDkyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkyMgogICAgICAgICAgICAgIGNhc2UgOTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTMwCiAgICAgICAgICAgICAgY2FzZSA5Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzOAogICAgICAgICAgICAgIGNhc2UgOTQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTQ2CiAgICAgICAgICAgICAgY2FzZSA5NTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NTQKICAgICAgICAgICAgICBjYXNlIDk2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NjIKICAgICAgICAgICAgICBjYXNlIDk3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NzAKICAgICAgICAgICAgICBjYXNlIDk3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NzgKICAgICAgICAgICAgICBjYXNlIDk4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5ODYKICAgICAgICAgICAgICBjYXNlIDk5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OTQKICAgICAgICAgICAgICBjYXNlIDEwMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAwMgogICAgICAgICAgICAgIGNhc2UgMTAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGbG9hdDEyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDEwCiAgICAgICAgICAgICAgY2FzZSAxMDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkludDMyMTI3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAxOAogICAgICAgICAgICAgIGNhc2UgMTAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwMjYKICAgICAgICAgICAgICBjYXNlIDEwMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDM0CiAgICAgICAgICAgICAgY2FzZSAxMDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0MgogICAgICAgICAgICAgIGNhc2UgMTA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNTAKICAgICAgICAgICAgICBjYXNlIDEwNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNTgKICAgICAgICAgICAgICBjYXNlIDEwNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNjYKICAgICAgICAgICAgICBjYXNlIDEwNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA3NAogICAgICAgICAgICAgIGNhc2UgMTA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyVWludDMyMTM1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA4MgogICAgICAgICAgICAgIGNhc2UgMTA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA5MAogICAgICAgICAgICAgIGNhc2UgMTA5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDk4CiAgICAgICAgICAgICAgY2FzZSAxMTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRCeXRlczEzOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMDYKICAgICAgICAgICAgICBjYXNlIDExMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTExNAogICAgICAgICAgICAgIGNhc2UgMTEyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RW51bTE0MF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTIyCiAgICAgICAgICAgICAgY2FzZSAxMTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMzAKICAgICAgICAgICAgICBjYXNlIDExMzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEzOAogICAgICAgICAgICAgIGNhc2UgMTE0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQ2CiAgICAgICAgICAgICAgY2FzZSAxMTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50MzIxNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRJbnQzMjE0NF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE1NAogICAgICAgICAgICAgIGNhc2UgMTE2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRJbnQ2NDE0NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNjIKICAgICAgICAgICAgICBjYXNlIDExNzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTcwCiAgICAgICAgICAgICAgY2FzZSAxMTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE3OAogICAgICAgICAgICAgIGNhc2UgMTE4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExODYKICAgICAgICAgICAgICBjYXNlIDExOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50MzIxNDlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExOTQKICAgICAgICAgICAgICBjYXNlIDEyMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMDIKICAgICAgICAgICAgICBjYXNlIDEyMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxMAogICAgICAgICAgICAgIGNhc2UgMTIxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxOAogICAgICAgICAgICAgIGNhc2UgMTIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyNgogICAgICAgICAgICAgIGNhc2UgMTIzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMzQKICAgICAgICAgICAgICBjYXNlIDEyNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjQyCiAgICAgICAgICAgICAgY2FzZSAxMjUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI1MAogICAgICAgICAgICAgIGNhc2UgMTI1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRW51bTE1N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRW51bTE1N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyNTgKICAgICAgICAgICAgICBjYXNlIDEyNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjY2CiAgICAgICAgICAgICAgY2FzZSAxMjc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI3NAogICAgICAgICAgICAgIGNhc2UgMTI4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyODIKICAgICAgICAgICAgICBjYXNlIDEyOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyOTAKICAgICAgICAgICAgICBjYXNlIDEyOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyOTgKICAgICAgICAgICAgICBjYXNlIDEzMDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMDYKICAgICAgICAgICAgICBjYXNlIDEzMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMTQKICAgICAgICAgICAgICBjYXNlIDEzMjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMjIKICAgICAgICAgICAgICBjYXNlIDEzMzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMzMAogICAgICAgICAgICAgIGNhc2UgMTMzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzM4CiAgICAgICAgICAgICAgY2FzZSAxMzQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM0NgogICAgICAgICAgICAgIGNhc2UgMTM1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzU0CiAgICAgICAgICAgICAgY2FzZSAxMzYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDY0MTcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNjIKICAgICAgICAgICAgICBjYXNlIDEzNzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJCb29sMTcxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM3MAogICAgICAgICAgICAgIGNhc2UgMTM3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCeXRlczE3MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzc4CiAgICAgICAgICAgICAgY2FzZSAxMzg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRG91YmxlMTczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzODYKICAgICAgICAgICAgICBjYXNlIDEzOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkVudW0xNzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkVudW0xNzRfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJFbnVtMTc0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM5NAogICAgICAgICAgICAgIGNhc2UgMTQwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDAyCiAgICAgICAgICAgICAgY2FzZSAxNDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MTAKICAgICAgICAgICAgICBjYXNlIDE0MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQxOAogICAgICAgICAgICAgIGNhc2UgMTQyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDMyMTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MjYKICAgICAgICAgICAgICBjYXNlIDE0MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDY0MTc5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMySW50NjQxNzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDM0CiAgICAgICAgICAgICAgY2FzZSAxNDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ0MgogICAgICAgICAgICAgIGNhc2UgMTQ1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NTAKICAgICAgICAgICAgICBjYXNlIDE0NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDU4CiAgICAgICAgICAgICAgY2FzZSAxNDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDY2CiAgICAgICAgICAgICAgY2FzZSAxNDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTaW50NjQxODRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDc0CiAgICAgICAgICAgICAgY2FzZSAxNDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0ODIKICAgICAgICAgICAgICBjYXNlIDE0OTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0OTAKICAgICAgICAgICAgICBjYXNlIDE0OTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0OTgKICAgICAgICAgICAgICBjYXNlIDE1MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRCb29sMTg4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUwNgogICAgICAgICAgICAgIGNhc2UgMTUxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTE0CiAgICAgICAgICAgICAgY2FzZSAxNTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MjIKICAgICAgICAgICAgICBjYXNlIDE1MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRFbnVtMTkxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRFbnVtMTkxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUzMAogICAgICAgICAgICAgIGNhc2UgMTUzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTM4CiAgICAgICAgICAgICAgY2FzZSAxNTQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NDYKICAgICAgICAgICAgICBjYXNlIDE1NTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RmxvYXQxOTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGbG9hdDE5NF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU1NAogICAgICAgICAgICAgIGNhc2UgMTU2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDMyMTk1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRJbnQzMjE5NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NjIKICAgICAgICAgICAgICBjYXNlIDE1NzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQ2NDE5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDY0MTk2X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTcwCiAgICAgICAgICAgICAgY2FzZSAxNTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU3OAogICAgICAgICAgICAgIGNhc2UgMTU4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1ODYKICAgICAgICAgICAgICBjYXNlIDE1OTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTk0CiAgICAgICAgICAgICAgY2FzZSAxNjAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAyCiAgICAgICAgICAgICAgY2FzZSAxNjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjEwCiAgICAgICAgICAgICAgY2FzZSAxNjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MTgKICAgICAgICAgICAgICBjYXNlIDE2MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MjYKICAgICAgICAgICAgICBjYXNlIDE2MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDJfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDNfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDRfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDVfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDZfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xCb29sMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQm9vbDFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xCb29sMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxXyA9IGZpZWxkTWFwQm9vbEJvb2wxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQm9vbDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwQm9vbEJvb2wxT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xCeXRlczJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfID0gZmllbGRNYXBCb29sQnl0ZXMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEJ5dGVzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEJvb2xEb3VibGUzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xEb3VibGUzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbERvdWJsZTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRG91YmxlM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfID0gZmllbGRNYXBCb29sRG91YmxlM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRG91YmxlM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sRW51bTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRW51bTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEVudW00XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRW51bTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF8gPSBmaWVsZE1hcEJvb2xFbnVtNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEJvb2xFbnVtNE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEVudW00VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBCb29sRW51bTRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEJvb2xFbnVtNE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00VmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEVudW00VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDMyNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDMyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRml4ZWQzMjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xGaXhlZDMyNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9IGZpZWxkTWFwQm9vbEZpeGVkMzI1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xGaXhlZDMyNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbEZpeGVkNjQ2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQ2NDZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEZpeGVkNjQ2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQ2NDZfID0gZmllbGRNYXBCb29sRml4ZWQ2NDZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xGaXhlZDY0NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGbG9hdDdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGbG9hdDdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEZsb2F0N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N18gPSBmaWVsZE1hcEJvb2xGbG9hdDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xGbG9hdDdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEZsb2F0NygKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEludDMyOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sSW50MzI4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEludDMyOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbEludDMyOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEludDMyOF8gPSBmaWVsZE1hcEJvb2xJbnQzMjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xJbnQzMjhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sSW50MzI4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEludDMyOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEludDY0OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDY0OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sSW50NjQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQ2NDlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xJbnQ2NDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQ2NDlfID0gZmllbGRNYXBCb29sSW50NjQ5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50NjQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDY0OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xJbnQ2NDkoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIgZmllbGRNYXBCb29sTWVzc2FnZTEwQ29udmVydGVyID0gbmV3IEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sTWVzc2FnZTEwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwQm9vbE1lc3NhZ2UxMEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTZml4ZWQzMjExXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBmaWVsZE1hcEJvb2xTZml4ZWQzMjExXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkNjQxMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ludDMyMTNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDMyMTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU2ludDMyMTNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50MzIxM18gPSBmaWVsZE1hcEJvb2xTaW50MzIxM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNpbnQzMjEzKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xTaW50NjQxNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50NjQxNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDY0MTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTaW50NjQxNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9IGZpZWxkTWFwQm9vbFNpbnQ2NDE0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU3RyaW5nMTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xTdHJpbmcxNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9IGZpZWxkTWFwQm9vbFN0cmluZzE1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU3RyaW5nMTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbFN0cmluZzE1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50MzIxNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sVWludDMyMTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xVaW50MzIxNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9IGZpZWxkTWFwQm9vbFVpbnQzMjE2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xVaW50MzIxNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFVpbnQ2NDE3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQ2NDE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbFVpbnQ2NDE3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfID0gZmllbGRNYXBCb29sVWludDY0MTdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xVaW50NjQxN09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQm9vbDE4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCb29sMThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkJvb2wxOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPSBmaWVsZE1hcEZpeGVkMzJCb29sMThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJCb29sMThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJCb29sMTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9IGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRG91YmxlMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJFbnVtMjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID0gZmllbGRNYXBGaXhlZDMyRW51bTIxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID0gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPSBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XyA9IGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMkludDMyMjVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkludDMyMjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XyA9IGZpZWxkTWFwRml4ZWQzMkludDMyMjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPSBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50NjQyNl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMySW50NjQyNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyID0gbmV3IEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPSBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID0gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9IGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDY0MzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9IGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPSBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfID0gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDMyMzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50NjQzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDY0MzRfID0gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDY0MzQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyVWludDY0MzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qm9vbDM1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCb29sMzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRCb29sMzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCb29sMzVfID0gZmllbGRNYXBGaXhlZDY0Qm9vbDM1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qm9vbDM1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XyA9IGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjREb3VibGUzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjREb3VibGUzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfID0gZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjREb3VibGUzNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0RW51bTM4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4XyA9IGZpZWxkTWFwRml4ZWQ2NEVudW0zOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDMyNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlciA9IG5ldyBGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID0gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0VWludDMyNTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0VWludDMyNTBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDY0NTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyQm9vbDUyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml8gPSBmaWVsZE1hcEludDMyQm9vbDUyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJ5dGVzNTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJ5dGVzNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCeXRlczUzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyQnl0ZXM1M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJCeXRlczUzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfID0gZmllbGRNYXBJbnQzMkJ5dGVzNTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJEb3VibGU1NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRG91YmxlNTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJEb3VibGU1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJEb3VibGU1NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBmaWVsZE1hcEludDMyRG91YmxlNTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRG91YmxlNTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRG91YmxlNTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRG91YmxlNTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJFbnVtNTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJFbnVtNTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkVudW01NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfID0gZmllbGRNYXBJbnQzMkVudW01NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkVudW01NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkVudW01NSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQzMjU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID0gZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQ2NDU3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQ2NDU3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJGaXhlZDY0NTdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XyA9IGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwSW50MzJGbG9hdDU4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRmxvYXQ1OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJGbG9hdDU4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGbG9hdDU4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkZsb2F0NThfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF8gPSBmaWVsZE1hcEludDMyRmxvYXQ1OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGbG9hdDU4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRmxvYXQ1OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkZsb2F0NTgoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyRmxvYXQ1OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyRmxvYXQ1OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMySW50MzI1OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMySW50MzI1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDMyNTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkludDMyNTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMySW50MzI1OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9IGZpZWxkTWFwSW50MzJJbnQzMjU5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDMyNTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMySW50NjQ2MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMySW50NjQ2MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMySW50NjQ2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkludDY0NjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMySW50NjQ2MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9IGZpZWxkTWFwSW50MzJJbnQ2NDYwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkludDY0NjAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkludDY0NjAoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlciBmaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyID0gbmV3IEZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcEludDMyTWVzc2FnZTYxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyTWVzc2FnZTYxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyTWVzc2FnZTYxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyTWVzc2FnZTYxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyTWVzc2FnZTYxXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9IGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9IGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlNpbnQzMjY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ludDMyNjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50MzI2NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlNpbnQzMjY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9IGZpZWxkTWFwSW50MzJTaW50MzI2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50NjQ2NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDY0NjVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyU2ludDY0NjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ludDY0NjVfID0gZmllbGRNYXBJbnQzMlNpbnQ2NDY1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwSW50MzJTdHJpbmc2Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU3RyaW5nNjZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU3RyaW5nNjZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyU3RyaW5nNjZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU3RyaW5nNjZfID0gZmllbGRNYXBJbnQzMlN0cmluZzY2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50MzI2N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyVWludDMyNjdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfID0gZmllbGRNYXBJbnQzMlVpbnQzMjY3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlVpbnQzMjY3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyVWludDMyNjcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJVaW50NjQ2OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDY0NjhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJVaW50NjQ2OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPSBmaWVsZE1hcEludDMyVWludDY0NjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyVWludDY0NjhPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Qm9vbDY5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Qm9vbDY5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRCb29sNjlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5XyA9IGZpZWxkTWFwSW50NjRCb29sNjlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qm9vbDY5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRCb29sNjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRCeXRlczcwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRCeXRlczcwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJ5dGVzNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0Qnl0ZXM3MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRCeXRlczcwXyA9IGZpZWxkTWFwSW50NjRCeXRlczcwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjREb3VibGU3MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RG91YmxlNzFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjREb3VibGU3MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjREb3VibGU3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjREb3VibGU3MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjREb3VibGU3MV8gPSBmaWVsZE1hcEludDY0RG91YmxlNzFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RG91YmxlNzFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RG91YmxlNzFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0RG91YmxlNzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0RW51bTcyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEVudW03Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RW51bTcyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEVudW03Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEVudW03Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0RW51bTcyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEVudW03Ml8gPSBmaWVsZE1hcEludDY0RW51bTcyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0RW51bTcyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0RW51bTcyVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Rml4ZWQzMjczXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Rml4ZWQzMjczXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQzMjczXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRGaXhlZDMyNzNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQzMjczXyA9IGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Rml4ZWQzMjczXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRGaXhlZDY0NzRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XyA9IGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGaXhlZDY0NzQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBJbnQ2NEZsb2F0NzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGbG9hdDc1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZsb2F0NzVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0RmxvYXQ3NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1XyA9IGZpZWxkTWFwSW50NjRGbG9hdDc1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZsb2F0NzVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRGbG9hdDc1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDMyNzZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQzMjc2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEludDMyNzZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl8gPSBmaWVsZE1hcEludDY0SW50MzI3Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQzMjc2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0SW50NjQ3N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0SW50NjQ3N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDY0NzdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQ2NDc3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0SW50NjQ3N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQ2NDc3XyA9IGZpZWxkTWFwSW50NjRJbnQ2NDc3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0SW50NjQ3NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRJbnQ2NDc3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRNZXNzYWdlNzhCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID0gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPSBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDMyODFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50MzI4MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFNpbnQzMjgxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9IGZpZWxkTWFwSW50NjRTaW50MzI4MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDY0ODJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRTaW50NjQ4Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPSBmaWVsZE1hcEludDY0U2ludDY0ODJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFN0cmluZzgzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTdHJpbmc4M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFN0cmluZzgzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9IGZpZWxkTWFwSW50NjRTdHJpbmc4M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U3RyaW5nODMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50MzI4NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0VWludDMyODRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfID0gZmllbGRNYXBJbnQ2NFVpbnQzMjg0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFVpbnQzMjg0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0VWludDY0ODVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50NjQ4NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFVpbnQ2NDg1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9IGZpZWxkTWFwSW50NjRVaW50NjQ4NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDY0ODVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl8gPSBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID0gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPSBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRW51bTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkVudW04OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfID0gZmllbGRNYXBTZml4ZWQzMkVudW04OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50MzI5M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50MzI5M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlciBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyID0gbmV3IEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9IGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID0gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPSBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XyA9IGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPSBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlciBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9IGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPSBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfID0gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfID0gZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9IGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPSBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8gPSBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJCb29sMTIwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJCb29sMTIwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJCb29sMTIwXyA9IGZpZWxkTWFwU2ludDMyQm9vbDEyMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkJvb2wxMjAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJCeXRlczEyMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJCeXRlczEyMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID0gZmllbGRNYXBTaW50MzJCeXRlczEyMV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyRG91YmxlMTIyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID0gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJEb3VibGUxMjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJEb3VibGUxMjIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyRW51bTEyM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJFbnVtMTIzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkVudW0xMjNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyRW51bTEyM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM18gPSBmaWVsZE1hcFNpbnQzMkVudW0xMjNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPSBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XyA9IGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJGbG9hdDEyNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID0gZmllbGRNYXBTaW50MzJGbG9hdDEyNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJJbnQzMjEyN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMySW50MzIxMjdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQzMjEyN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMySW50MzIxMjdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJJbnQzMjEyN18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50MzIxMjdfID0gZmllbGRNYXBTaW50MzJJbnQzMjEyN18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMySW50MzIxMjdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJJbnQzMjEyNygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMySW50MzIxMjcoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMySW50NjQxMjhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50NjQxMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMySW50NjQxMjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMySW50NjQxMjhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9IGZpZWxkTWFwU2ludDMySW50NjQxMjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlciBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9IGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8gPSBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ludDMyMTMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfID0gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTaW50MzIxMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ludDY0MTMzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfID0gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJTaW50NjQxMzMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJVaW50MzIxMzVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJVaW50MzIxMzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPSBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJVaW50NjQxMzZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJVaW50NjQxMzZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPSBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDY0Qm9vbDEzN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRCb29sMTM3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCb29sMTM3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0Qm9vbDEzN18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRCeXRlczEzOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gZmllbGRNYXBTaW50NjRCeXRlczEzOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjREb3VibGUxMzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8gPSBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RW51bTE0MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRFbnVtMTQwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEVudW0xNDBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID0gZmllbGRNYXBTaW50NjRFbnVtMTQwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDY0RW51bTE0ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID0gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0RmxvYXQxNDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9IGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRGbG9hdDE0MygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRJbnQzMjE0NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRJbnQzMjE0NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRJbnQzMjE0NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gZmllbGRNYXBTaW50NjRJbnQzMjE0NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyID0gbmV3IEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPSBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPSBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50MzIxNDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRTaW50MzIxNDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPSBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGZpZWxkTWFwU2ludDY0VWludDMyMTUyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0VWludDY0MTUzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0VWludDY0MTUzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID0gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nQm9vbDE1NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9IGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0VudW0xNTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0VudW0xNTdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfID0gZmllbGRNYXBTdHJpbmdFbnVtMTU3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID0gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9IGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nSW50MzIxNjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50NjQxNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ludDY0MTYyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8gPSBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0ludDY0MTYyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+IGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M18gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8gPSBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfID0gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9IGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9IGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPSBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID0gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID0gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQm9vbDE3MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJCb29sMTcxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkJvb2wxNzFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID0gZmllbGRNYXBVaW50MzJCb29sMTcxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBVaW50MzJCeXRlczE3Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPSBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCeXRlczE3Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRG91YmxlMTczXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRG91YmxlMTczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRG91YmxlMTczXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRG91YmxlMTczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJEb3VibGUxNzNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPSBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRG91YmxlMTczXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkVudW0xNzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJFbnVtMTc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRW51bTE3NF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJFbnVtMTc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJFbnVtMTc0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9IGZpZWxkTWFwVWludDMyRW51bTE3NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRW51bTE3NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJFbnVtMTc0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9IGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID0gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBVaW50MzJGbG9hdDE3N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkZsb2F0MTc3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N18gPSBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGbG9hdDE3N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDMyMTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkludDMyMTc4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPSBmaWVsZE1hcFVpbnQzMkludDMyMTc4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQzMjE3OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJJbnQzMjE3OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMySW50NjQxNzlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMySW50NjQxNzlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMySW50NjQxNzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMySW50NjQxNzlfID0gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMySW50NjQxNzlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMySW50NjQxNzlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPiBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfID0gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9IGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTaW50MzIxODNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50MzIxODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDMyMTgzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTaW50MzIxODNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPSBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTaW50NjQxODRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDY0MTg0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTaW50NjQxODRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPSBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyU3RyaW5nMTg1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfID0gZmllbGRNYXBVaW50MzJTdHJpbmcxODVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTdHJpbmcxODUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJVaW50MzIxODZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50MzIxODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9IGZpZWxkTWFwVWludDMyVWludDMyMTg2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJVaW50NjQxODdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9IGZpZWxkTWFwVWludDMyVWludDY0MTg3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50NjRCb29sMTg4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJvb2wxODhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRCb29sMTg4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4XyA9IGZpZWxkTWFwVWludDY0Qm9vbDE4OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qm9vbDE4OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRCb29sMTg4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPSBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwVWludDY0RG91YmxlMTkwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjREb3VibGUxOTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjREb3VibGUxOTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RG91YmxlMTkwXyA9IGZpZWxkTWFwVWludDY0RG91YmxlMTkwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0RW51bTE5MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV8gPSBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPSBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGbG9hdDE5NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRGbG9hdDE5NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID0gZmllbGRNYXBVaW50NjRGbG9hdDE5NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NEludDMyMTk1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDMyMTk1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEludDMyMTk1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPSBmaWVsZE1hcFVpbnQ2NEludDMyMTk1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0SW50MzIxOTUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEludDY0MTk2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPSBmaWVsZE1hcFVpbnQ2NEludDY0MTk2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlciBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmcuUHJvdG8zTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9IGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9IGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50MzIyMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9IGZpZWxkTWFwVWludDY0U2ludDMyMjAwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDMyMjAwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ludDMyMjAwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ludDY0MjAxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDY0MjAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ludDY0MjAxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID0gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U3RyaW5nMjAyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID0gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDMyMjAzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0VWludDMyMjAzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID0gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0VWludDMyMjAzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRVaW50NjQyMDRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPSBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nLlByb3RvM01lc3NhZ2VXaXRoTWFwcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM01lc3NhZ2VXaXRoTWFwcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzNNZXNzYWdlV2l0aE1hcHM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBQcm90bzNNZXNzYWdlV2l0aE1hcHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzNNZXNzYWdlV2l0aE1hcHM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zTWVzc2FnZVdpdGhNYXBzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZy5Qcm90bzNNZXNzYWdlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM1NwZWNpYWxGaWVsZE5hbWVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM1NwZWNpYWxGaWVsZE5hbWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQm9vbDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQnl0ZXMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xEb3VibGUzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xEb3VibGUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEVudW00RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkNjQxMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkNjQxMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQzMjEzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQzMjE2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQzMjI1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQzMjI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDMyMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDMyMzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50MzI0MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50MzI0MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDMyNDdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDMyNTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDY0NTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGbG9hdDU4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDMyNTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50MzI2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQ2NDY1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU3RyaW5nNjZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQ2NDY4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCeXRlczcwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NERvdWJsZTcxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDMyODFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50NjQ4MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDMyODRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50NjQ4NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50MzI5M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCb29sMTIwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGbG9hdDEyNkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGbG9hdDEyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDMyMTM1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDY0MTM2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQ2NDE0NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQ2NDE0NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQm9vbDE1NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRW51bTE1N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDMyMTgzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDY0MTg0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDMyMTg2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RG91YmxlMTkwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RW51bTE5MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQ2NDE5NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQ2NDE5NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuKGNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8zX21lc3NhZ2UucHJvIiArCiAgICAgICJ0b1wwMjJcMDI1cHJvdG9idWYuZXhwZXJpbWVudGFsXCJrXG5cMDI2UHJvdG8zU3BlY2kiICsKICAgICAgImFsRmllbGROYW1lXDAyMlwwMjRcblwwMTRyZWd1bGFyX25hbWVcMDMwXDAwMSBcMDAxKFwwMDFcMDIyXDAyM1xuXDAxM2NhYyIgKwogICAgICAiaGVkX3NpemVcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAyN1xuXDAxN3NlcmlhbGl6ZWRfc2l6ZVwwMzBcMDAzIFwwMDEoXDAwM1wwMjIiICsKICAgICAgIlxyXG5cMDA1Y2xhc3NcMDMwXDAwNCBcMDAxKFx0XCJcMjIyXDAyMlxuXHJQcm90bzNNZXNzYWdlXDAyMlwwMjZcblwwMTZmaWVsIiArCiAgICAgICJkX2RvdWJsZV8xXDAzMFwwMDEgXDAwMShcMDAxXDAyMlwwMjVcblxyZmllbGRfZmxvYXRfMlwwMzBcMDAyIFwwMDEoXDAwMlwwMjIiICsKICAgICAgIlwwMjVcblxyZmllbGRfaW50NjRfM1wwMzBcMDAzIFwwMDEoXDAwM1wwMjJcMDI2XG5cMDE2ZmllbGRfdWludDY0XzQiICsKICAgICAgIlwwMzBcMDA0IFwwMDEoXDAwNFwwMjJcMDI1XG5ccmZpZWxkX2ludDMyXzVcMDMwXDAwNSBcMDAxKFwwMDVcMDIyXDAyN1xuXDAxN2ZpZWxkX2YiICsKICAgICAgIml4ZWQ2NF82XDAzMFwwMDYgXDAwMShcMDA2XDAyMlwwMjdcblwwMTdmaWVsZF9maXhlZDMyXzdcMDMwXDAwNyBcMDAxKFwwMDdcMDIyIiArCiAgICAgICJcMDI0XG5cMDE0ZmllbGRfYm9vbF84XDAzMFwwMTAgXDAwMShcMDEwXDAyMlwwMjZcblwwMTZmaWVsZF9zdHJpbmdfOVwwMzAiICsKICAgICAgIlx0IFwwMDEoXHRcMDIyPlxuXDAyMGZpZWxkX21lc3NhZ2VfMTBcMDMwXG4gXDAwMShcMDEzMiQucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVwwMjJcMDI2XG5cMDE2ZmllbGRfYiIgKwogICAgICAieXRlc18xMVwwMzBcMDEzIFwwMDEoXDAxNFwwMjJcMDI3XG5cMDE3ZmllbGRfdWludDMyXzEyXDAzMFwwMTQgXDAwMShcclwwMjJEIiArCiAgICAgICJcblxyZmllbGRfZW51bV8xM1wwMzBcciBcMDAxKFwwMTYyLS5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtXDAyMlwwMzFcblwwMjFmaWVsZF9zZiIgKwogICAgICAiaXhlZDMyXzE0XDAzMFwwMTYgXDAwMShcMDE3XDAyMlwwMzFcblwwMjFmaWVsZF9zZml4ZWQ2NF8xNVwwMzBcMDE3IFwwMDEiICsKICAgICAgIihcMDIwXDAyMlwwMjdcblwwMTdmaWVsZF9zaW50MzJfMTZcMDMwXDAyMCBcMDAxKFwwMjFcMDIyXDAyN1xuXDAxN2ZpZWxkX3NpbiIgKwogICAgICAidDY0XzE3XDAzMFwwMjEgXDAwMShcMDIyXDAyMiBcblwwMjRmaWVsZF9kb3VibGVfbGlzdF8xOFwwMzBcMDIyIFwwMDMiICsKICAgICAgIihcMDAxQlwwMDJcMDIwXDAwMFwwMjJcMDM3XG5cMDIzZmllbGRfZmxvYXRfbGlzdF8xOVwwMzBcMDIzIFwwMDMoXDAwMkJcMDAyXDAyMFwwMDBcMDIyIiArCiAgICAgICJcMDM3XG5cMDIzZmllbGRfaW50NjRfbGlzdF8yMFwwMzBcMDI0IFwwMDMoXDAwM0JcMDAyXDAyMFwwMDBcMDIyIFxuXDAyNGZpZWwiICsKICAgICAgImRfdWludDY0X2xpc3RfMjFcMDMwXDAyNSBcMDAzKFwwMDRCXDAwMlwwMjBcMDAwXDAyMlwwMzdcblwwMjNmaWVsZF9pbnQzIiArCiAgICAgICIyX2xpc3RfMjJcMDMwXDAyNiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAwXDAyMiFcblwwMjVmaWVsZF9maXhlZDY0X2xpcyIgKwogICAgICAidF8yM1wwMzBcMDI3IFwwMDMoXDAwNkJcMDAyXDAyMFwwMDBcMDIyIVxuXDAyNWZpZWxkX2ZpeGVkMzJfbGlzdF8yNFwwMzAiICsKICAgICAgIlwwMzAgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMFwwMjJcMDM2XG5cMDIyZmllbGRfYm9vbF9saXN0XzI1XDAzMFwwMzEgXDAwMyhcMDEwQlwwMDJcMDIwIiArCiAgICAgICJcMDAwXDAyMiBcblwwMjRmaWVsZF9zdHJpbmdfbGlzdF8yNlwwMzBcMDMyIFwwMDMoXHRCXDAwMlwwMjBcMDAwXDAyMkdcblwwMjVmIiArCiAgICAgICJpZWxkX21lc3NhZ2VfbGlzdF8yN1wwMzBcMDMzIFwwMDMoXDAxMzIkLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VCXDAwMlwwMjBcMDAwXDAyMlwwMzdcblwwMjNmaWVsZF9ieSIgKwogICAgICAidGVzX2xpc3RfMjhcMDMwXDAzNCBcMDAzKFwwMTRCXDAwMlwwMjBcMDAwXDAyMiBcblwwMjRmaWVsZF91aW50MzJfbGkiICsKICAgICAgInN0XzI5XDAzMFwwMzUgXDAwMyhcckJcMDAyXDAyMFwwMDBcMDIyTVxuXDAyMmZpZWxkX2VudW1fbGlzdF8zMFwwMzBcMDM2ICIgKwogICAgICAiXDAwMyhcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZyIgKwogICAgICAiZS5UZXN0RW51bUJcMDAyXDAyMFwwMDBcMDIyXCJcblwwMjZmaWVsZF9zZml4ZWQzMl9saXN0XzMxIiArCiAgICAgICJcMDMwXDAzNyBcMDAzKFwwMTdCXDAwMlwwMjBcMDAwXDAyMlwiXG5cMDI2ZmllbGRfc2ZpeGVkNjRfbGlzdF8zMlwwMzAgIFwwMDMiICsKICAgICAgIihcMDIwQlwwMDJcMDIwXDAwMFwwMjIgXG5cMDI0ZmllbGRfc2ludDMyX2xpc3RfMzNcMDMwISBcMDAzKFwwMjFCXDAwMlwwMjBcMDAwIiArCiAgICAgICJcMDIyIFxuXDAyNGZpZWxkX3NpbnQ2NF9saXN0XzM0XDAzMFwiIFwwMDMoXDAyMkJcMDAyXDAyMFwwMDBcMDIyXCdcblwwMzNmaSIgKwogICAgICAiZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNVwwMzAjIFwwMDMoXDAwMUJcMDAyXDAyMFwwMDFcMDIyJlxuXDAzMmYiICsKICAgICAgImllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzZcMDMwJCBcMDAzKFwwMDJCXDAwMlwwMjBcMDAxXDAyMiZcblwwMzJmIiArCiAgICAgICJpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3XDAzMCUgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMVwwMjJcJ1xuXDAzM2YiICsKICAgICAgImllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4XDAzMCYgXDAwMyhcMDA0QlwwMDJcMDIwXDAwMVwwMjImXG5cMDMyIiArCiAgICAgICJmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOVwwMzBcJyBcMDAzKFwwMDVCXDAwMlwwMjBcMDAxXDAyMihcblwwMzQiICsKICAgICAgImZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDBcMDMwKCBcMDAzKFwwMDZCXDAwMlwwMjBcMDAxXDAyMigiICsKICAgICAgIlxuXDAzNGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDFcMDMwKSBcMDAzKFwwMDdCXDAwMlwwMjBcMDAxIiArCiAgICAgICJcMDIyJVxuXDAzMWZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDJcMDMwKiBcMDAzKFwwMTBCXDAwMlwwMjBcMDAxXDAyMiIgKwogICAgICAiXCdcblwwMzNmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDNcMDMwKyBcMDAzKFxyQlwwMDJcMDIwXDAwMSIgKwogICAgICAiXDAyMlRcblwwMzFmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0XDAzMCwgXDAwMyhcMDE2Mi0ucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW4iICsKICAgICAgInVtQlwwMDJcMDIwXDAwMVwwMjIpXG5cMDM1ZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDVcMDMwIiArCiAgICAgICItIFwwMDMoXDAxN0JcMDAyXDAyMFwwMDFcMDIyKVxuXDAzNWZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXyIgKwogICAgICAiNDZcMDMwLiBcMDAzKFwwMjBCXDAwMlwwMjBcMDAxXDAyMlwnXG5cMDMzZmllbGRfc2ludDMyX2xpc3RfcGFja2VkIiArCiAgICAgICJfNDdcMDMwLyBcMDAzKFwwMjFCXDAwMlwwMjBcMDAxXDAyMlwnXG5cMDMzZmllbGRfc2ludDY0X2xpc3RfcGFja2UiICsKICAgICAgImRfNDhcMDMwMCBcMDAzKFwwMjJCXDAwMlwwMjBcMDAxXDAyMlwwMzFcblwwMTdmaWVsZF9kb3VibGVfNTNcMDMwNSBcMDAxKFwwMDFIIiArCiAgICAgICJcMDAwXDAyMlwwMzBcblwwMTZmaWVsZF9mbG9hdF81NFwwMzA2IFwwMDEoXDAwMkhcMDAwXDAyMlwwMzBcblwwMTZmaWVsZF9pbnQiICsKICAgICAgIjY0XzU1XDAzMDcgXDAwMShcMDAzSFwwMDBcMDIyXDAzMVxuXDAxN2ZpZWxkX3VpbnQ2NF81NlwwMzA4IFwwMDEoXDAwNEhcMDAwIiArCiAgICAgICJcMDIyXDAzMFxuXDAxNmZpZWxkX2ludDMyXzU3XDAzMDkgXDAwMShcMDA1SFwwMDBcMDIyXDAzMlxuXDAyMGZpZWxkX2ZpeGUiICsKICAgICAgImQ2NF81OFwwMzA6IFwwMDEoXDAwNkhcMDAwXDAyMlwwMzJcblwwMjBmaWVsZF9maXhlZDMyXzU5XDAzMDsgXDAwMShcMDA3IiArCiAgICAgICJIXDAwMFwwMjJcMDI3XG5ccmZpZWxkX2Jvb2xfNjBcMDMwPCBcMDAxKFwwMTBIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfc3RyIiArCiAgICAgICJpbmdfNjFcMDMwPSBcMDAxKFx0SFwwMDBcMDIyQFxuXDAyMGZpZWxkX21lc3NhZ2VfNjJcMDMwPiBcMDAxKFwwMTMiICsKICAgICAgIjIkLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlSFwwMDAiICsKICAgICAgIlwwMjJcMDMwXG5cMDE2ZmllbGRfYnl0ZXNfNjNcMDMwPyBcMDAxKFwwMTRIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfdWludCIgKwogICAgICAiMzJfNjRcMDMwQCBcMDAxKFxySFwwMDBcMDIyXDAzM1xuXDAyMWZpZWxkX3NmaXhlZDMyXzY1XDAzMEEgXDAwMShcMDE3IiArCiAgICAgICJIXDAwMFwwMjJcMDMzXG5cMDIxZmllbGRfc2ZpeGVkNjRfNjZcMDMwQiBcMDAxKFwwMjBIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGQiICsKICAgICAgIl9zaW50MzJfNjdcMDMwQyBcMDAxKFwwMjFIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfc2ludDY0XzY4XDAzMEQgIiArCiAgICAgICJcMDAxKFwwMjJIXDAwMFwiJlxuXDAxMFRlc3RFbnVtXDAyMlwwMTBcblwwMDRaRVJPXDAyMFwwMDBcMDIyXDAwN1xuXDAwM09ORVwwMjBcMDAxXDAyMlwwMDdcblwwMDMiICsKICAgICAgIlRXT1wwMjBcMDAyQlwwMTRcblxudGVzdF9vbmVvZlwiXHJcblwwMTNQcm90bzNFbXB0eVwiXDIzNlwyMzdcMDAyXG5cMDI1IiArCiAgICAgICJQcm90bzNNZXNzYWdlV2l0aE1hcHNcMDIyYlxuXDAyNWZpZWxkX21hcF9ib29sXyIgKwogICAgICAiYm9vbF8xXDAzMFwwMDEgXDAwMyhcMDEzMkMucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEJvb2wxRW50ciIgKwogICAgICAieVwwMjJkXG5cMDI2ZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMlwwMzBcMDAyIFwwMDMoXDAxMzJELnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5XDAyMmZcblwwMjdmaWVsZF9tYXBfYm9vIiArCiAgICAgICJsX2RvdWJsZV8zXDAzMFwwMDMgXDAwMyhcMDEzMkUucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbERvdWJsIiArCiAgICAgICJlM0VudHJ5XDAyMmJcblwwMjVmaWVsZF9tYXBfYm9vbF9lbnVtXzRcMDMwXDAwNCBcMDAzKFwwMTMyQyIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aCIgKwogICAgICAiTWFwcy5GaWVsZE1hcEJvb2xFbnVtNEVudHJ5XDAyMmhcblwwMzBmaWVsZF9tYXAiICsKICAgICAgIl9ib29sX2ZpeGVkMzJfNVwwMzBcMDA1IFwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cGVyaW0iICsKICAgICAgImVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEJvb2wiICsKICAgICAgIkZpeGVkMzI1RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfIiArCiAgICAgICI2XDAzMFwwMDYgXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lIiArCiAgICAgICJzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlcMDIyIiArCiAgICAgICJkXG5cMDI2ZmllbGRfbWFwX2Jvb2xfZmxvYXRfN1wwMzBcMDA3IFwwMDMoXDAxMzJELnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwQm9vbEZsb2F0N0VudHJ5XDAyMmRcblwwMjZmaWVsZF9tYXBfYm9vbF8iICsKICAgICAgImludDMyXzhcMDMwXDAxMCBcMDAzKFwwMTMyRC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHIiICsKICAgICAgIm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBCb29sSW50MzI4RW4iICsKICAgICAgInRyeVwwMjJkXG5cMDI2ZmllbGRfbWFwX2Jvb2xfaW50NjRfOVwwMzBcdCBcMDAzKFwwMTMyRC5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcCIgKwogICAgICAicy5GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2IiICsKICAgICAgIm9vbF9tZXNzYWdlXzEwXDAzMFxuIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEJvb2xNIiArCiAgICAgICJlc3NhZ2UxMEVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMiIgKwogICAgICAiXzExXDAzMFwwMTMgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbiIgKwogICAgICAidHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMlwwMzBcMDE0IFwwMDMoXDAxMzIiICsKICAgICAgIkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXQiICsKICAgICAgImhNYXBzLkZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeVwwMjJoXG5cMDMwZmllIiArCiAgICAgICJsZF9tYXBfYm9vbF9zaW50MzJfMTNcMDMwXHIgXDAwMyhcMDEzMkYucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBCb29sU2ludDMyMTNFbnRyeVwwMjJoXG5cMDMwZmllbGRfbWFwX2Jvb2xfc2kiICsKICAgICAgIm50NjRfMTRcMDMwXDAxNiBcMDAzKFwwMTMyRi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHIiICsKICAgICAgIm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBCb29sU2ludDY0MTQiICsKICAgICAgIkVudHJ5XDAyMmhcblwwMzBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTVcMDMwXDAxNyBcMDAzKFwwMTMyIiArCiAgICAgICJGLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0IiArCiAgICAgICJoTWFwcy5GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5XDAyMmhcblwwMzBmaWVsZCIgKwogICAgICAiX21hcF9ib29sX3VpbnQzMl8xNlwwMzBcMDIwIFwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiQm9vbFVpbnQzMjE2RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9ib29sX3VpbnQiICsKICAgICAgIjY0XzE3XDAzMFwwMjEgXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3QiICsKICAgICAgIm8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwQm9vbFVpbnQ2NDE3RW4iICsKICAgICAgInRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOFwwMzBcMDIyIFwwMDMoXDAxMzJHIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5XDAyMmxcblwwMzJmaWVsZCIgKwogICAgICAiX21hcF9maXhlZDMyX2J5dGVzXzE5XDAzMFwwMjMgXDAwMyhcMDEzMkgucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBGaXhlZDMyQnl0ZXMxOUVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQiICsKICAgICAgIjMyX2RvdWJsZV8yMFwwMzBcMDI0IFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzIiICsKICAgICAgIkRvdWJsZTIwRW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9maXhlZDMyX2VudW1fIiArCiAgICAgICIyMVwwMzBcMDI1IFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNIiArCiAgICAgICJlc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyIiArCiAgICAgICJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyXDAzMFwwMjYgXDAwMyhcMDEzMiIgKwogICAgICAiSi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdCIgKwogICAgICAiaE1hcHMuRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlcMDIycFxuXDAzNGYiICsKICAgICAgImllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yM1wwMzBcMDI3IFwwMDMoXDAxMzJKLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5XDAyMmxcblwwMzJmaWVsZF9tIiArCiAgICAgICJhcF9maXhlZDMyX2Zsb2F0XzI0XDAzMFwwMzAgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwIiArCiAgICAgICJGaXhlZDMyRmxvYXQyNEVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfZml4ZWQzMiIgKwogICAgICAiX2ludDMyXzI1XDAzMFwwMzEgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMkludCIgKwogICAgICAiMzIyNUVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNlwwMzAiICsKICAgICAgIlwwMzIgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeVwwMjIiICsKICAgICAgInBcblwwMzRmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3XDAzMFwwMzMgXDAwMyhcMDEzMkouIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNIiArCiAgICAgICJhcHMuRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlcMDIyclxuXDAzNWZpZSIgKwogICAgICAibGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjhcMDMwXDAzNCBcMDAzKFwwMTMySy5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RW50cnlcMDIyclxuXDAzNWZpZWxkX20iICsKICAgICAgImFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjlcMDMwXDAzNSBcMDAzKFwwMTMySy5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGQiICsKICAgICAgIk1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlcMDIyblxuXDAzM2ZpZWxkX21hcF9mIiArCiAgICAgICJpeGVkMzJfc2ludDMyXzMwXDAzMFwwMzYgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4IiArCiAgICAgICJlZDMyU2ludDMyMzBFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX2ZpeGVkMzJfcyIgKwogICAgICAiaW50NjRfMzFcMDMwXDAzNyBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyU2ludCIgKwogICAgICAiNjQzMUVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIiICsKICAgICAgIlwwMzAgIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXMiICsKICAgICAgInNhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHIiICsKICAgICAgInlcMDIyblxuXDAzM2ZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zM1wwMzAhIFwwMDMoXDAxMzJJIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlcMDIyblxuXDAzM2ZpZSIgKwogICAgICAibGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0XDAzMFwiIFwwMDMoXDAxMzJJLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9mIiArCiAgICAgICJpeGVkNjRfYm9vbF8zNVwwMzAjIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkIiArCiAgICAgICI2NEJvb2wzNUVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlcyIgKwogICAgICAiXzM2XDAzMCQgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbiIgKwogICAgICAidHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzdcMDMwJSBcMDAzKFwwMTMiICsKICAgICAgIjJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5XDAyMmpcblwwMzFmIiArCiAgICAgICJpZWxkX21hcF9maXhlZDY0X2VudW1fMzhcMDMwJiBcMDAzKFwwMTMyRy5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeVwwMjJwXG5cMDM0ZmllbGRfbWFwX2ZpeCIgKwogICAgICAiZWQ2NF9maXhlZDMyXzM5XDAzMFwnIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW0iICsKICAgICAgImVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGUiICsKICAgICAgImQ2NEZpeGVkMzIzOUVudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfZml4ZWQ2NF9mIiArCiAgICAgICJpeGVkNjRfNDBcMDMwKCBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDY0Rml4IiArCiAgICAgICJlZDY0NDBFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNCIgKwogICAgICAiMVwwMzApIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50ciIgKwogICAgICAieVwwMjJsXG5cMDMyZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDJcMDMwKiBcMDAzKFwwMTMySC4iICsKICAgICAgInByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE0iICsKICAgICAgImFwcy5GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlcMDIybFxuXDAzMmZpZWxkIiArCiAgICAgICJfbWFwX2ZpeGVkNjRfaW50NjRfNDNcMDMwKyBcMDAzKFwwMTMySC5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcEZpeGVkNjRJbnQ2NDQzRW50cnlcMDIycFxuXDAzNGZpZWxkX21hcF9maXhlZCIgKwogICAgICAiNjRfbWVzc2FnZV80NFwwMzAsIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbiIgKwogICAgICAidGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNiIgKwogICAgICAiNE1lc3NhZ2U0NEVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfZml4ZWQ2NF9zZmkiICsKICAgICAgInhlZDMyXzQ1XDAzMC0gXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NFNmaXgiICsKICAgICAgImVkMzI0NUVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2IiArCiAgICAgICI0XzQ2XDAzMC4gXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvIiArCiAgICAgICIzTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0IiArCiAgICAgICI0NkVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDdcMDMwLyIgKwogICAgICAiIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYSIgKwogICAgICAiZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5XDAyMiIgKwogICAgICAiblxuXDAzM2ZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OFwwMzAwIFwwMDMoXDAxMzJJLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlcMDIyblxuXDAzM2ZpZWxkIiArCiAgICAgICJfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5XDAzMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX2ZpeCIgKwogICAgICAiZWQ2NF91aW50MzJfNTBcMDMwMiBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZSIgKwogICAgICAibnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBGaXhlZCIgKwogICAgICAiNjRVaW50MzI1MEVudHJ5XDAyMm5cblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF91aW4iICsKICAgICAgInQ2NF81MVwwMzAzIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm8iICsKICAgICAgInRvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjRVaW50NjQiICsKICAgICAgIjUxRW50cnlcMDIyZlxuXDAyN2ZpZWxkX21hcF9pbnQzMl9ib29sXzUyXDAzMDQgXDAwMyhcMDEzIiArCiAgICAgICIyRS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5XDAyMmhcblwwMzBmaWVsZCIgKwogICAgICAiX21hcF9pbnQzMl9ieXRlc181M1wwMzA1IFwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiSW50MzJCeXRlczUzRW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9pbnQzMl9kb3UiICsKICAgICAgImJsZV81NFwwMzA2IFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm8iICsKICAgICAgInRvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyRG91YmxlNTQiICsKICAgICAgIkVudHJ5XDAyMmZcblwwMjdmaWVsZF9tYXBfaW50MzJfZW51bV81NVwwMzA3IFwwMDMoXDAxMzJFIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeVwwMjJsXG5cMDMyZmllbGRfbSIgKwogICAgICAiYXBfaW50MzJfZml4ZWQzMl81NlwwMzA4IFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiSW50MzJGaXhlZDMyNTZFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX2ludDMyX2YiICsKICAgICAgIml4ZWQ2NF81N1wwMzA5IFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyRml4ZWQiICsKICAgICAgIjY0NTdFbnRyeVwwMjJoXG5cMDMwZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4XDAzMDogIiArCiAgICAgICJcMDAzKFwwMTMyRi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnIiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeVwwMjJoXG5cMDMwZiIgKwogICAgICAiaWVsZF9tYXBfaW50MzJfaW50MzJfNTlcMDMwOyBcMDAzKFwwMTMyRi5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbCIgKwogICAgICAiZE1hcEludDMySW50MzI1OUVudHJ5XDAyMmhcblwwMzBmaWVsZF9tYXBfaW50MzIiICsKICAgICAgIl9pbnQ2NF82MFwwMzA8IFwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMySW50NjQiICsKICAgICAgIjYwRW50cnlcMDIybFxuXDAzMmZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxXDAzMD0gIiArCiAgICAgICJcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnIiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5XDAyMm5cbiIgKwogICAgICAiXDAzM2ZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MlwwMzA+IFwwMDMoXDAxMzJJLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlcMDIyblxuXDAzM2ZpZWxkX20iICsKICAgICAgImFwX2ludDMyX3NmaXhlZDY0XzYzXDAzMD8gXDAwMyhcMDEzMkkucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBJbnQzMlNmaXhlZDY0NjNFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ludDMyIiArCiAgICAgICJfc2ludDMyXzY0XDAzMEAgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50MzJTaW50IiArCiAgICAgICIzMjY0RW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjVcMDMwQSIgKwogICAgICAiIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYSIgKwogICAgICAiZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeVwwMjJqXG4iICsKICAgICAgIlwwMzFmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2XDAzMEIgXDAwMyhcMDEzMkcucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9pIiArCiAgICAgICJudDMyX3VpbnQzMl82N1wwMzBDIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEludDMyIiArCiAgICAgICJVaW50MzI2N0VudHJ5XDAyMmpcblwwMzFmaWVsZF9tYXBfaW50MzJfdWludDY0XyIgKwogICAgICAiNjhcMDMwRCBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTSIgKwogICAgICAiZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQzMlVpbnQ2NDY4RW50ciIgKwogICAgICAieVwwMjJmXG5cMDI3ZmllbGRfbWFwX2ludDY0X2Jvb2xfNjlcMDMwRSBcMDAzKFwwMTMyRS5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMiICsKICAgICAgIi5GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9pIiArCiAgICAgICJudDY0X2J5dGVzXzcwXDAzMEYgXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRCIiArCiAgICAgICJ5dGVzNzBFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSIgKwogICAgICAiXDAzMEcgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lcyIgKwogICAgICAic2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5XDAyMiIgKwogICAgICAiZlxuXDAyN2ZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyXDAzMEggXDAwMyhcMDEzMkUucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBJbnQ2NEVudW03MkVudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfaW50IiArCiAgICAgICI2NF9maXhlZDMyXzczXDAzMEkgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRGIiArCiAgICAgICJpeGVkMzI3M0VudHJ5XDAyMmxcblwwMzJmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NCIgKwogICAgICAiXzc0XDAzMEogXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbiIgKwogICAgICAidHJ5XDAyMmhcblwwMzBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzVcMDMwSyBcMDAzKFwwMTMyRi4iICsKICAgICAgInByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE0iICsKICAgICAgImFwcy5GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5XDAyMmhcblwwMzBmaWVsZF9tIiArCiAgICAgICJhcF9pbnQ2NF9pbnQzMl83NlwwMzBMIFwwMDMoXDAxMzJGLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcEluIiArCiAgICAgICJ0NjRJbnQzMjc2RW50cnlcMDIyaFxuXDAzMGZpZWxkX21hcF9pbnQ2NF9pbnQ2NCIgKwogICAgICAiXzc3XDAzME0gXDAwMyhcMDEzMkYucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRJbnQ2NDc3RW50ciIgKwogICAgICAieVwwMjJsXG5cMDMyZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzhcMDMwTiBcMDAzKFwwMTMySC4iICsKICAgICAgInByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE0iICsKICAgICAgImFwcy5GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlcMDIyblxuXDAzM2ZpZWxkIiArCiAgICAgICJfbWFwX2ludDY0X3NmaXhlZDMyXzc5XDAzME8gXDAwMyhcMDEzMkkucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX2ludCIgKwogICAgICAiNjRfc2ZpeGVkNjRfODBcMDMwUCBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZSIgKwogICAgICAibnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NCIgKwogICAgICAiU2ZpeGVkNjQ4MEVudHJ5XDAyMmpcblwwMzFmaWVsZF9tYXBfaW50NjRfc2ludDMiICsKICAgICAgIjJfODFcMDMwUSBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW4iICsKICAgICAgInRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MlwwMzBSIFwwMDMoXDAxMzJHIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwSW50NjRTaW50NjQ4MkVudHJ5XDAyMmpcblwwMzFmaWVsZCIgKwogICAgICAiX21hcF9pbnQ2NF9zdHJpbmdfODNcMDMwUyBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leCIgKwogICAgICAicGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYSIgKwogICAgICAicEludDY0U3RyaW5nODNFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwX2ludDY0X3UiICsKICAgICAgImludDMyXzg0XDAzMFQgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRVaW50MzIiICsKICAgICAgIjg0RW50cnlcMDIyalxuXDAzMWZpZWxkX21hcF9pbnQ2NF91aW50NjRfODVcMDMwVSBcMDAzIiArCiAgICAgICIoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeVwwMjJsXG5cMDMyZiIgKwogICAgICAiaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NlwwMzBWIFwwMDMoXDAxMzJILnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX3MiICsKICAgICAgImZpeGVkMzJfYnl0ZXNfODdcMDMwVyBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZmkiICsKICAgICAgInhlZDMyQnl0ZXM4N0VudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ZpeGVkMzJfIiArCiAgICAgICJkb3VibGVfODhcMDMwWCBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkRvIiArCiAgICAgICJ1YmxlODhFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fOCIgKwogICAgICAiOVwwMzBZIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50ciIgKwogICAgICAieVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTBcMDMwWiBcMDAzKFwwMTMiICsKICAgICAgIjJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlcMDIyclxuIiArCiAgICAgICJcMDM1ZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTFcMDMwWyBcMDAzKFwwMTMySy5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRW50cnlcMDIyblxuXDAzM2ZpZSIgKwogICAgICAibGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyXDAzMFxcIFwwMDMoXDAxMzJJLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlcMDIyblxuXDAzM2ZpZWxkX21hcF9zIiArCiAgICAgICJmaXhlZDMyX2ludDMyXzkzXDAzMF0gXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpIiArCiAgICAgICJ4ZWQzMkludDMyOTNFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX3NmaXhlZDMyXyIgKwogICAgICAiaW50NjRfOTRcMDMwXiBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkludCIgKwogICAgICAiNjQ5NEVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV8iICsKICAgICAgIjk1XDAzMF8gXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM00iICsKICAgICAgImVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUiICsKICAgICAgIkVudHJ5XDAyMnRcblwwMzZmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTZcMDMwIiArCiAgICAgICJgIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzIiArCiAgICAgICJhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVuIiArCiAgICAgICJ0cnlcMDIydFxuXDAzNmZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85N1wwMzBhICIgKwogICAgICAiXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZyIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50ciIgKwogICAgICAieVwwMjJwXG5cMDM0ZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OFwwMzBiIFwwMDMoXDAxMzIiICsKICAgICAgIkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXQiICsKICAgICAgImhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5XDAyMnBcblwwMzRmIiArCiAgICAgICJpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTlcMDMwYyBcMDAzKFwwMTMySi5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuIiArCiAgICAgICJGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbSIgKwogICAgICAiYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMFwwMzBkIFwwMDMoXDAxMzJLLnByb3RvYnVmLiIgKwogICAgICAiZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZCIgKwogICAgICAiTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3MiICsKICAgICAgImZpeGVkMzJfdWludDMyXzEwMVwwMzBlIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFMiICsKICAgICAgImZpeGVkMzJVaW50MzIxMDFFbnRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlIiArCiAgICAgICJkMzJfdWludDY0XzEwMlwwMzBmIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlIiArCiAgICAgICJkMzJVaW50NjQxMDJFbnRyeVwwMjJuXG5cMDMzZmllbGRfbWFwX3NmaXhlZDY0XyIgKwogICAgICAiYm9vbF8xMDNcMDMwZyBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NEJvbyIgKwogICAgICAibDEwM0VudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTAiICsKICAgICAgIjRcMDMwaCBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWUiICsKICAgICAgInNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW4iICsKICAgICAgInRyeVwwMjJyXG5cMDM1ZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDVcMDMwaSBcMDAzIiArCiAgICAgICIoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlcMDIyIiArCiAgICAgICJuXG5cMDMzZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2XDAzMGogXDAwMyhcMDEzMkkucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeVwwMjJ0XG5cMDM2ZmllbGQiICsKICAgICAgIl9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDdcMDMwayBcMDAzKFwwMTMyTC5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmkiICsKICAgICAgImVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5XDAyMnRcblwwMzZmaWVsZF9tIiArCiAgICAgICJhcF9zZml4ZWQ2NF9maXhlZDY0XzEwOFwwMzBsIFwwMDMoXDAxMzJMLnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlcMDIycFxuXDAzNGZpZWxkX21hcCIgKwogICAgICAiX3NmaXhlZDY0X2Zsb2F0XzEwOVwwMzBtIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcCIgKwogICAgICAiU2ZpeGVkNjRGbG9hdDEwOUVudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ZpeGUiICsKICAgICAgImQ2NF9pbnQzMl8xMTBcMDMwbiBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQiICsKICAgICAgIjY0SW50MzIxMTBFbnRyeVwwMjJwXG5cMDM0ZmllbGRfbWFwX3NmaXhlZDY0X2luIiArCiAgICAgICJ0NjRfMTExXDAzMG8gXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRJbnQ2IiArCiAgICAgICI0MTExRW50cnlcMDIydFxuXDAzNmZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXyIgKwogICAgICAiMTEyXDAzMHAgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMSIgKwogICAgICAiMTJFbnRyeVwwMjJ2XG5cMDM3ZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzEiICsKICAgICAgIjEzXDAzMHEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM00iICsKICAgICAgImVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjEiICsKICAgICAgIjEzRW50cnlcMDIydlxuXDAzN2ZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xIiArCiAgICAgICIxNFwwMzByIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNIiArCiAgICAgICJlc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxIiArCiAgICAgICIxNEVudHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSIgKwogICAgICAiXDAzMHMgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lcyIgKwogICAgICAic2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbiIgKwogICAgICAidHJ5XDAyMnJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNlwwMzB0IFwwMDMiICsKICAgICAgIihcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeVwwMjIiICsKICAgICAgInJcblwwMzVmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExN1wwMzB1IFwwMDMoXDAxMzJLIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeVwwMjJyXG5cMDM1ZiIgKwogICAgICAiaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOFwwMzB2IFwwMDMoXDAxMzJLLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeVwwMjJyXG5cMDM1ZmllbGQiICsKICAgICAgIl9tYXBfc2ZpeGVkNjRfdWludDY0XzExOVwwMzB3IFwwMDMoXDAxMzJLLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeVwwMjJqXG5cMDMxZmllbGRfbWFwIiArCiAgICAgICJfc2ludDMyX2Jvb2xfMTIwXDAzMHggXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2luIiArCiAgICAgICJ0MzJCb29sMTIwRW50cnlcMDIybFxuXDAzMmZpZWxkX21hcF9zaW50MzJfYnl0ZSIgKwogICAgICAic18xMjFcMDMweSBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdCIgKwogICAgICAibzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJCeXRlczEyMSIgKwogICAgICAiRW50cnlcMDIyblxuXDAzM2ZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMlwwMzB6IFwwMDMiICsKICAgICAgIihcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2UiLAogICAgICAiV2l0aE1hcHMuRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeVwwMjJqXG4iICsKICAgICAgIlwwMzFmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzXDAzMHsgXDAwMyhcMDEzMkcucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlcMDIycFxuXDAzNGZpZWxkX21hcF9zIiArCiAgICAgICJpbnQzMl9maXhlZDMyXzEyNFwwMzB8IFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpIiArCiAgICAgICJudDMyRml4ZWQzMjEyNEVudHJ5XDAyMnBcblwwMzRmaWVsZF9tYXBfc2ludDMyXyIgKwogICAgICAiZml4ZWQ2NF8xMjVcMDMwfSBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YSIgKwogICAgICAibC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJGaSIgKwogICAgICAieGVkNjQxMjVFbnRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8iICsKICAgICAgIjEyNlwwMzB+IFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzMiICsKICAgICAgIk1lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW4iICsKICAgICAgInRyeVwwMjJsXG5cMDMyZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjdcMDMwXDE3NyBcMDAzKFwwMTMyIiArCiAgICAgICJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0IiArCiAgICAgICJoTWFwcy5GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlcMDIybVxuXDAzMmZpZSIgKwogICAgICAibGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjhcMDMwXDIwMFwwMDEgXDAwMyhcMDEzMkgucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZSIgKwogICAgICAibGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5XDAyMnFcblwwMzRmaWVsZF9tYXBfc2kiICsKICAgICAgIm50MzJfbWVzc2FnZV8xMjlcMDMwXDIwMVwwMDEgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2kiICsKICAgICAgIm50MzJNZXNzYWdlMTI5RW50cnlcMDIyc1xuXDAzNWZpZWxkX21hcF9zaW50MzJfIiArCiAgICAgICJzZml4ZWQzMl8xMzBcMDMwXDIwMlwwMDEgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDMyIiArCiAgICAgICJTZml4ZWQzMjEzMEVudHJ5XDAyMnNcblwwMzVmaWVsZF9tYXBfc2ludDMyX3NmaSIgKwogICAgICAieGVkNjRfMTMxXDAzMFwyMDNcMDAxIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMlNmaSIgKwogICAgICAieGVkNjQxMzFFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQzMl9zaW50MzIiICsKICAgICAgIl8xMzJcMDMwXDIwNFwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3QiICsKICAgICAgIm8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDMyU2ludDMyMTMiICsKICAgICAgIjJFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzXDAzMFwyMDVcMDAxIiArCiAgICAgICIgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhIiArCiAgICAgICJnZVdpdGhNYXBzLkZpZWxkTWFwU2ludDMyU2ludDY0MTMzRW50cnlcMDIyIiArCiAgICAgICJvXG5cMDMzZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0XDAzMFwyMDZcMDAxIFwwMDMoXDAxMzJJLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTSIgKwogICAgICAiYXBzLkZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RW50cnlcMDIyb1xuXDAzM2ZpZWwiICsKICAgICAgImRfbWFwX3NpbnQzMl91aW50MzJfMTM1XDAzMFwyMDdcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwU2ludDMyVWludDMyMTM1RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zIiArCiAgICAgICJpbnQzMl91aW50NjRfMTM2XDAzMFwyMTBcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpIiArCiAgICAgICJudDMyVWludDY0MTM2RW50cnlcMDIya1xuXDAzMWZpZWxkX21hcF9zaW50NjRfYiIgKwogICAgICAib29sXzEzN1wwMzBcMjExXDAwMSBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRCb29sMSIgKwogICAgICAiMzdFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzhcMDMwXDIxMlwwMDEiICsKICAgICAgIiBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2EiICsKICAgICAgImdlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5XDAyMm8iICsKICAgICAgIlxuXDAzM2ZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOVwwMzBcMjEzXDAwMSBcMDAzKFwwMTMySS5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5XDAyMmtcblwwMzFmaWVsZCIgKwogICAgICAiX21hcF9zaW50NjRfZW51bV8xNDBcMDMwXDIxNFwwMDEgXDAwMyhcMDEzMkcucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBTaW50NjRFbnVtMTQwRW50cnlcMDIycVxuXDAzNGZpZWxkX21hcF9zaW50NjQiICsKICAgICAgIl9maXhlZDMyXzE0MVwwMzBcMjE1XDAwMSBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50NjQiICsKICAgICAgIkZpeGVkMzIxNDFFbnRyeVwwMjJxXG5cMDM0ZmllbGRfbWFwX3NpbnQ2NF9maXhlIiArCiAgICAgICJkNjRfMTQyXDAzMFwyMTZcMDAxIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QIiArCiAgICAgICJyb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEZpeGVkIiArCiAgICAgICI2NDE0MkVudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyIgKwogICAgICAiXDAzMFwyMTdcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50ciIgKwogICAgICAieVwwMjJtXG5cMDMyZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDRcMDMwXDIyMFwwMDEgXDAwMyhcMDEzMkgiICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTaW50NjRJbnQzMjE0NEVudHJ5XDAyMm1cblwwMzJmaWVsIiArCiAgICAgICJkX21hcF9zaW50NjRfaW50NjRfMTQ1XDAzMFwyMjFcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmIiArCiAgICAgICIuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwU2ludDY0SW50NjQxNDVFbnRyeVwwMjJxXG5cMDM0ZmllbGRfbWFwX3NpbiIgKwogICAgICAidDY0X21lc3NhZ2VfMTQ2XDAzMFwyMjJcMDAxIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaSIgKwogICAgICAibWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbiIgKwogICAgICAidDY0TWVzc2FnZTE0NkVudHJ5XDAyMnNcblwwMzVmaWVsZF9tYXBfc2ludDY0X3MiICsKICAgICAgImZpeGVkMzJfMTQ3XDAzMFwyMjNcMDAxIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NFMiICsKICAgICAgImZpeGVkMzIxNDdFbnRyeVwwMjJzXG5cMDM1ZmllbGRfbWFwX3NpbnQ2NF9zZml4IiArCiAgICAgICJlZDY0XzE0OFwwMzBcMjI0XDAwMSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRTZml4IiArCiAgICAgICJlZDY0MTQ4RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zaW50NjRfc2ludDMyXyIgKwogICAgICAiMTQ5XDAzMFwyMjVcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90byIgKwogICAgICAiM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSIgKwogICAgICAiRW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MFwwMzBcMjI2XDAwMSAiICsKICAgICAgIlwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWciICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5XDAyMm8iICsKICAgICAgIlxuXDAzM2ZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MVwwMzBcMjI3XDAwMSBcMDAzKFwwMTMySS5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5XDAyMm9cblwwMzNmaWVsZCIgKwogICAgICAiX21hcF9zaW50NjRfdWludDMyXzE1MlwwMzBcMjMwXDAwMSBcMDAzKFwwMTMySS5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbCIgKwogICAgICAiZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc2kiICsKICAgICAgIm50NjRfdWludDY0XzE1M1wwMzBcMjMxXDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTaW4iICsKICAgICAgInQ2NFVpbnQ2NDE1M0VudHJ5XDAyMmtcblwwMzFmaWVsZF9tYXBfc3RyaW5nX2JvIiArCiAgICAgICJvbF8xNTRcMDMwXDIzMlwwMDEgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nQm9vbDE1IiArCiAgICAgICI0RW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1XDAzMFwyMzNcMDAxICIgKwogICAgICAiXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZyIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeVwwMjJvXG4iICsKICAgICAgIlwwMzNmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTZcMDMwXDIzNFwwMDEgXDAwMyhcMDEzMkkucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeVwwMjJrXG5cMDMxZmllbGRfIiArCiAgICAgICJtYXBfc3RyaW5nX2VudW1fMTU3XDAzMFwyMzVcMDAxIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwU3RyaW5nRW51bTE1N0VudHJ5XDAyMnFcblwwMzRmaWVsZF9tYXBfc3RyaW5nXyIgKwogICAgICAiZml4ZWQzMl8xNThcMDMwXDIzNlwwMDEgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nRiIgKwogICAgICAiaXhlZDMyMTU4RW50cnlcMDIycVxuXDAzNGZpZWxkX21hcF9zdHJpbmdfZml4ZWQiICsKICAgICAgIjY0XzE1OVwwMzBcMjM3XDAwMSBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHIiICsKICAgICAgIm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdGaXhlZDYiICsKICAgICAgIjQxNTlFbnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjBcMDMwIiArCiAgICAgICJcMjQwXDAwMSBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzIiArCiAgICAgICJzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5IiArCiAgICAgICJcMDIybVxuXDAzMmZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxXDAzMFwyNDFcMDAxIFwwMDMoXDAxMzJILiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTSIgKwogICAgICAiYXBzLkZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeVwwMjJtXG5cMDMyZmllbGQiICsKICAgICAgIl9tYXBfc3RyaW5nX2ludDY0XzE2MlwwMzBcMjQyXDAwMSBcMDAzKFwwMTMySC5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGQiICsKICAgICAgIk1hcFN0cmluZ0ludDY0MTYyRW50cnlcMDIycVxuXDAzNGZpZWxkX21hcF9zdHJpIiArCiAgICAgICJuZ19tZXNzYWdlXzE2M1wwMzBcMjQzXDAwMSBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltIiArCiAgICAgICJlbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpIiArCiAgICAgICJuZ01lc3NhZ2UxNjNFbnRyeVwwMjJzXG5cMDM1ZmllbGRfbWFwX3N0cmluZ19zZiIgKwogICAgICAiaXhlZDMyXzE2NFwwMzBcMjQ0XDAwMSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YSIgKwogICAgICAibC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdTZiIgKwogICAgICAiaXhlZDMyMTY0RW50cnlcMDIyc1xuXDAzNWZpZWxkX21hcF9zdHJpbmdfc2ZpeGUiICsKICAgICAgImQ2NF8xNjVcMDMwXDI0NVwwMDEgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nU2ZpeGUiICsKICAgICAgImQ2NDE2NUVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xIiArCiAgICAgICI2NlwwMzBcMjQ2XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zIiArCiAgICAgICJNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFIiArCiAgICAgICJudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjdcMDMwXDI0N1wwMDEgXDAwMyIgKwogICAgICAiKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSIgKwogICAgICAiV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeVwwMjJvXG4iICsKICAgICAgIlwwMzNmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjhcMDMwXDI1MFwwMDEgXDAwMyhcMDEzMkkucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeVwwMjJvXG5cMDMzZmllbGRfIiArCiAgICAgICJtYXBfc3RyaW5nX3VpbnQzMl8xNjlcMDMwXDI1MVwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBTdHJpbmdVaW50MzIxNjlFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3N0ciIgKwogICAgICAiaW5nX3VpbnQ2NF8xNzBcMDMwXDI1MlwwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbSIgKwogICAgICAiZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwU3RyaSIgKwogICAgICAibmdVaW50NjQxNzBFbnRyeVwwMjJrXG5cMDMxZmllbGRfbWFwX3VpbnQzMl9ib28iICsKICAgICAgImxfMTcxXDAzMFwyNTNcMDAxIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm8iICsKICAgICAgInRvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkJvb2wxNzEiICsKICAgICAgIkVudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MlwwMzBcMjU0XDAwMSBcMDAzIiArCiAgICAgICIoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlcMDIyb1xuXDAzMyIgKwogICAgICAiZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczXDAzMFwyNTVcMDAxIFwwMDMoXDAxMzJJLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlcMDIya1xuXDAzMWZpZWxkX20iICsKICAgICAgImFwX3VpbnQzMl9lbnVtXzE3NFwwMzBcMjU2XDAwMSBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIlVpbnQzMkVudW0xNzRFbnRyeVwwMjJxXG5cMDM0ZmllbGRfbWFwX3VpbnQzMl9mIiArCiAgICAgICJpeGVkMzJfMTc1XDAzMFwyNTdcMDAxIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbnRhIiArCiAgICAgICJsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkZpIiArCiAgICAgICJ4ZWQzMjE3NUVudHJ5XDAyMnFcblwwMzRmaWVsZF9tYXBfdWludDMyX2ZpeGVkNiIgKwogICAgICAiNF8xNzZcMDMwXDI2MFwwMDEgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlBybyIgKwogICAgICAidG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyRml4ZWQ2NCIgKwogICAgICAiMTc2RW50cnlcMDIybVxuXDAzMmZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3XDAzMFwyNjEiICsKICAgICAgIlwwMDEgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeVwwMjIiICsKICAgICAgIm1cblwwMzJmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OFwwMzBcMjYyXDAwMSBcMDAzKFwwMTMySC5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlcMDIybVxuXDAzMmZpZWxkXyIgKwogICAgICAibWFwX3VpbnQzMl9pbnQ2NF8xNzlcMDMwXDI2M1wwMDEgXDAwMyhcMDEzMkgucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBVaW50MzJJbnQ2NDE3OUVudHJ5XDAyMnFcblwwMzRmaWVsZF9tYXBfdWludDMiICsKICAgICAgIjJfbWVzc2FnZV8xODBcMDMwXDI2NFwwMDEgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWUiICsKICAgICAgIm50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMiICsKICAgICAgIjJNZXNzYWdlMTgwRW50cnlcMDIyc1xuXDAzNWZpZWxkX21hcF91aW50MzJfc2ZpIiArCiAgICAgICJ4ZWQzMl8xODFcMDMwXDI2NVwwMDEgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsIiArCiAgICAgICIuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyU2ZpIiArCiAgICAgICJ4ZWQzMjE4MUVudHJ5XDAyMnNcblwwMzVmaWVsZF9tYXBfdWludDMyX3NmaXhlZCIgKwogICAgICAiNjRfMTgyXDAzMFwyNjZcMDAxIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QciIgKwogICAgICAib3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMlNmaXhlZCIgKwogICAgICAiNjQxODJFbnRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgiICsKICAgICAgIjNcMDMwXDI2N1wwMDEgXDAwMyhcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM00iICsKICAgICAgImVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyU2ludDMyMTgzRW4iICsKICAgICAgInRyeVwwMjJvXG5cMDMzZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0XDAzMFwyNzBcMDAxIFwwMDMoIiArCiAgICAgICJcMDEzMkkucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXIiArCiAgICAgICJpdGhNYXBzLkZpZWxkTWFwVWludDMyU2ludDY0MTg0RW50cnlcMDIyb1xuXDAzMyIgKwogICAgICAiZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1XDAzMFwyNzFcMDAxIFwwMDMoXDAxMzJJLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlcMDIyb1xuXDAzM2ZpZWxkX20iICsKICAgICAgImFwX3VpbnQzMl91aW50MzJfMTg2XDAzMFwyNzJcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE0iICsKICAgICAgImFwVWludDMyVWludDMyMTg2RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF91aW50IiArCiAgICAgICIzMl91aW50NjRfMTg3XDAzMFwyNzNcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lIiArCiAgICAgICJudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQzIiArCiAgICAgICIyVWludDY0MTg3RW50cnlcMDIya1xuXDAzMWZpZWxkX21hcF91aW50NjRfYm9vbCIgKwogICAgICAiXzE4OFwwMzBcMjc0XDAwMSBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdCIgKwogICAgICAibzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50NjRCb29sMTg4RSIgKwogICAgICAibnRyeVwwMjJtXG5cMDMyZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODlcMDMwXDI3NVwwMDEgXDAwMygiICsKICAgICAgIlwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVciICsKICAgICAgIml0aE1hcHMuRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5XDAyMm9cblwwMzNmIiArCiAgICAgICJpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MFwwMzBcMjc2XDAwMSBcMDAzKFwwMTMySS5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuIiArCiAgICAgICJGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5XDAyMmtcblwwMzFmaWVsZF9tYSIgKwogICAgICAicF91aW50NjRfZW51bV8xOTFcMDMwXDI3N1wwMDEgXDAwMyhcMDEzMkcucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXBzLkZpZWxkTWFwVSIgKwogICAgICAiaW50NjRFbnVtMTkxRW50cnlcMDIycVxuXDAzNGZpZWxkX21hcF91aW50NjRfZmkiICsKICAgICAgInhlZDMyXzE5MlwwMzBcMzAwXDAwMSBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwiICsKICAgICAgIi5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50NjRGaXgiICsKICAgICAgImVkMzIxOTJFbnRyeVwwMjJxXG5cMDM0ZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0IiArCiAgICAgICJfMTkzXDAzMFwzMDFcMDAxIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90IiArCiAgICAgICJvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxIiArCiAgICAgICI5M0VudHJ5XDAyMm1cblwwMzJmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NFwwMzBcMzAyXDAwMSIgKwogICAgICAiIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYSIgKwogICAgICAiZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlcMDIybSIgKwogICAgICAiXG5cMDMyZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTVcMDMwXDMwM1wwMDEgXDAwMyhcMDEzMkgucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5XDAyMm1cblwwMzJmaWVsZF9tIiArCiAgICAgICJhcF91aW50NjRfaW50NjRfMTk2XDAzMFwzMDRcMDAxIFwwMDMoXDAxMzJILnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwVWludDY0SW50NjQxOTZFbnRyeVwwMjJxXG5cMDM0ZmllbGRfbWFwX3VpbnQ2NCIgKwogICAgICAiX21lc3NhZ2VfMTk3XDAzMFwzMDVcMDAxIFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyaW1lbiIgKwogICAgICAidGFsLlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NCIgKwogICAgICAiTWVzc2FnZTE5N0VudHJ5XDAyMnNcblwwMzVmaWVsZF9tYXBfdWludDY0X3NmaXgiICsKICAgICAgImVkMzJfMTk4XDAzMFwzMDZcMDAxIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NFNmaXgiICsKICAgICAgImVkMzIxOThFbnRyeVwwMjJzXG5cMDM1ZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2IiArCiAgICAgICI0XzE5OVwwMzBcMzA3XDAwMSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvIiArCiAgICAgICJ0bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50NjRTZml4ZWQ2IiArCiAgICAgICI0MTk5RW50cnlcMDIyb1xuXDAzM2ZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCIgKwogICAgICAiXDAzMFwzMTBcMDAxIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2VXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudCIgKwogICAgICAicnlcMDIyb1xuXDAzM2ZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMVwwMzBcMzExXDAwMSBcMDAzKFwwMTMiICsKICAgICAgIjJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5XDAyMm9cblwwMzNmIiArCiAgICAgICJpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMlwwMzBcMzEyXDAwMSBcMDAzKFwwMTMySS5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuIiArCiAgICAgICJGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5XDAyMm9cblwwMzNmaWVsZF9tYSIgKwogICAgICAicF91aW50NjRfdWludDMyXzIwM1wwMzBcMzEzXDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leCIgKwogICAgICAicGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYSIgKwogICAgICAicFVpbnQ2NFVpbnQzMjIwM0VudHJ5XDAyMm9cblwwMzNmaWVsZF9tYXBfdWludDYiICsKICAgICAgIjRfdWludDY0XzIwNFwwMzBcMzE0XDAwMSBcMDAzKFwwMTMySS5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzNNZXNzYWdlV2l0aE1hcHMuRmllbGRNYXBVaW50NjQiICsKICAgICAgIlVpbnQ2NDIwNEVudHJ5XDAzMjhcblwwMjZGaWVsZE1hcEJvb2xCb29sMUVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI5XG5cMDI3RmllbCIgKwogICAgICAiZE1hcEJvb2xCeXRlczJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyOlxuXDAzMEZpZWxkTWFwQm9vbERvdWJsZTNFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyZ1xuXDAyNkZpZWxkIiArCiAgICAgICJNYXBCb29sRW51bTRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMjxcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwQm9vbEZpeGVkMzI1IiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMjtcbiIgKwogICAgICAiXDAzMUZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMjlcblwwMjdGaWVsZE1hcEJvb2xGbG9hdDciICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyOVxuIiArCiAgICAgICJcMDI3RmllbGRNYXBCb29sSW50MzI4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjlcblwwMjdGaWVsZE1hcEJvb2xJbnQ2NDlFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyYlxuXDAzMkYiICsKICAgICAgImllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjIzIiArCiAgICAgICJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QciIgKwogICAgICAib3RvM01lc3NhZ2U6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEJvb2xTZml4ZWQzMjEiICsKICAgICAgIjFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMj0iICsKICAgICAgIlxuXDAzM0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwQm9vbFNpbiIgKwogICAgICAidDMyMTNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xTIiArCiAgICAgICJ0cmluZzE1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdCIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBCb29sVWludDMyMTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvbyIgKwogICAgICAibFVpbnQ2NDE3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMDQ6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwIiArCiAgICAgICJGaXhlZDMyQnl0ZXMxOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMya1xuXDAzMkYiICsKICAgICAgImllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjI8IiArCiAgICAgICJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QciIgKwogICAgICAib3RvM01lc3NhZ2UuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcEZpeGUiICsKICAgICAgImQzMkZpeGVkMzIyMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaSIgKwogICAgICAiZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyIiArCiAgICAgICJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQzMkludDMiICsKICAgICAgIjIyNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI9XG5cMDMzRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJlXG5cMDM1RmllbGRNYXBGaXhlZCIgKwogICAgICAiMzJNZXNzYWdlMjdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDEzMiQucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhIiArCiAgICAgICJnZTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWwiICsKICAgICAgImRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyIiArCiAgICAgICJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDMyU2luIiArCiAgICAgICJ0MzIzMEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRmkiICsKICAgICAgInhlZDMyU3RyaW5nMzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpIiArCiAgICAgICJlbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwRml4ZWQ2NEJvbyIgKwogICAgICAibDM1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMSIgKwogICAgICAiXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkIiArCiAgICAgICI2NERvdWJsZTM3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgIiArCiAgICAgICJcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmtcblwwMzJGaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNSIgKwogICAgICAiRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEiICsKICAgICAgIihcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcEZpeGVkNjQiICsKICAgICAgIkZpeGVkNjQ0MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYSIgKwogICAgICAicEZpeGVkNjRJbnQzMjQyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmVcblwwMzVGIiArCiAgICAgICJpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNlwwMjIzXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZW50YWwiICsKICAgICAgIi5Qcm90bzNNZXNzYWdlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBGaXhlZDY0U2ZpIiArCiAgICAgICJ4ZWQzMjQ1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3IiArCiAgICAgICI6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE0iICsKICAgICAgImFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0IiArCiAgICAgICI4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+IiArCiAgICAgICJcblwwMzRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRml4ZWQ2IiArCiAgICAgICI0VWludDMyNTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXHI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI6XG5cMDMwRmllbGRNIiArCiAgICAgICJhcEludDMyQm9vbDUyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMTA6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGQiICsKICAgICAgIk1hcEludDMyRG91YmxlNTRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyaVxuXDAzMEZpZWxkTWFwSW50MzJFbnVtNTVFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bTpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI9XG5cMDMzRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBJbnQzMiIgKwogICAgICAiRml4ZWQ2NDU3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMDY6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJIiArCiAgICAgICJudDMySW50MzI1OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyY1xuXDAzM0ZpZWxkTWEiICsKICAgICAgInBJbnQzMk1lc3NhZ2U2MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyM1xuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTSIgKwogICAgICAiZXNzYWdlOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpIiArCiAgICAgICJlbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJTaW50MyIgKwogICAgICAiMjY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMSIgKwogICAgICAiXDAzMjxcblwwMzJGaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50MzJTIiArCiAgICAgICJ0cmluZzY2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdCIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbiIgKwogICAgICAidDMyVWludDY0NjhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyOlxuXDAzMEZpZWxkTWFwSW50NjRCb29sNjlFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwIiArCiAgICAgICJJbnQ2NEJ5dGVzNzBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJpXG5cMDMwRmllbGQiICsKICAgICAgIk1hcEludDY0RW51bTcyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjI8XG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2UuVGVzdEVudW06XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludDY0Rml4ZWQiICsKICAgICAgIjMyNzNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjgiICsKICAgICAgIlwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50NiIgKwogICAgICAiNEZsb2F0NzVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKCIgKwogICAgICAiXDAwMjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEluIiArCiAgICAgICJ0NjRJbnQ2NDc3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgIiArCiAgICAgICJcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmNcblwwMzNGaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLlByb3RvM01lc3NhZ2U6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcCIgKwogICAgICAiSW50NjRTZml4ZWQzMjc5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI8XG5cMDMyIiArCiAgICAgICJGaWVsZE1hcEludDY0U2ludDMyODFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50NjRTaW50NiIgKwogICAgICAiNDgyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMSIgKwogICAgICAiXDAzMjxcblwwMzJGaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDY0VSIgKwogICAgICAiaW50MzI4NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHIiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50NjRVaW50NjQ4NUVudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTZiIgKwogICAgICAiaXhlZDMyQm9vbDg2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMCIgKwogICAgICAiXDAwMiBcMDAxKFwwMTA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllIiArCiAgICAgICJsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMybFxuXDAzM0ZpZWxkTWFwU2ZpeGVkMzJFbiIgKwogICAgICAidW04OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0uIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0IiArCiAgICAgICJFbnVtOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmkiICsKICAgICAgImVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNmaXhlZDMyIiArCiAgICAgICJGbG9hdDkyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNmaXhlZDMySW50MzI5M0VudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlNmaXhlZDMySW50NjQ5NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJmXG5cMDM2RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5IiArCiAgICAgICI1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjIzXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlOlwwMDI4XDAwMVwwMzJBXG5cMDM3IiArCiAgICAgICJGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJBXG5cMDM3RmllbGRNYXBTZml4ZSIgKwogICAgICAiZDMyU2ZpeGVkNjQ5N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj9cblwwMzVGIiArCiAgICAgICJpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIsCiAgICAgICJcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDMyIiArCiAgICAgICJTdHJpbmcxMDBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXHQ6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbCIgKwogICAgICAiZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNmaXhlZDY0Qm8iICsKICAgICAgIm9sMTAzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwUyIgKwogICAgICAiZml4ZWQ2NERvdWJsZTEwNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJtXG5cMDM0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYiICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzJBXG5cMDM3RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyQVxuXDAzN0ZpZWxkIiArCiAgICAgICJNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU2ZpeGVkNjRGbCIgKwogICAgICAib2F0MTA5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOiIgKwogICAgICAiXDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwIiArCiAgICAgICJTZml4ZWQ2NEludDY0MTExRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhIiArCiAgICAgICJsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmdcblwwMzdGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZSIgKwogICAgICAiMTEyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjIzXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlOlwwMDI4XDAwMVwwMzJCIiArCiAgICAgICJcbiBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQlxuIEZpZWxkTWFwU2YiICsKICAgICAgIml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDY0U2ludDMyIiArCiAgICAgICIxMTVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2YiICsKICAgICAgIml4ZWQ2NFN0cmluZzExN0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMSIgKwogICAgICAiOEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMkAiICsKICAgICAgIlxuXDAzNkZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwU2ludCIgKwogICAgICAiMzJCb29sMTIwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMTA6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hIiArCiAgICAgICJwU2ludDMyRG91YmxlMTIyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhIiArCiAgICAgICJsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmtcblwwMzJGaWVsZE1hcFNpbnQzMkVudW0xMjNFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyPFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mi0ucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZS5UZXN0RW51bTpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlcMDIyXDAxM1xuXDAwM2siICsKICAgICAgImV5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFMiICsKICAgICAgImludDMyRml4ZWQ2NDEyNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTaW50MzJGbG9hdDEyNkVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRiIgKwogICAgICAiaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQzMkludDYiICsKICAgICAgIjQxMjhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjgiICsKICAgICAgIlwwMDFcMDMyZVxuXDAzNUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUVudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXDAyMVwwMjIzXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJC5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzNNZXNzYWdlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTaW50IiArCiAgICAgICIzMlNmaXhlZDMyMTMwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzQiICsKICAgICAgIkZpZWxkTWFwU2ludDMyU2ludDMyMTMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlNpIiArCiAgICAgICJudDY0MTMzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwIiArCiAgICAgICJTaW50MzJVaW50MzIxMzVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyIiArCiAgICAgICJGaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDY0Qnl0ZSIgKwogICAgICAiczEzOEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOCIgKwogICAgICAiXDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMya1xuXDAzMkZpZWxkTWFwU2luIiArCiAgICAgICJ0NjRFbnVtMTQwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWciICsKICAgICAgImUuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxIiArCiAgICAgICI0MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI/XG5cMDM1RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQiICsKICAgICAgIjY0RmxvYXQxNDNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTSIgKwogICAgICAiYXBTaW50NjRJbnQ2NDE0NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJlXG5cMDM1RmllbGRNYXBTaW50NjRNZXNzYWdlMTQiICsKICAgICAgIjZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2U6XDAwMjhcMDAxXDAzMkBcblwwMzYiICsKICAgICAgIkZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ludDY0IiArCiAgICAgICJTZml4ZWQ2NDE0OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWwiICsKICAgICAgImRNYXBTaW50NjRTaW50NjQxNTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDY0U3RyaW5nIiArCiAgICAgICIxNTFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMSIgKwogICAgICAiXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludCIgKwogICAgICAiNjRVaW50NjQxNTNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwU3RyaW5nQm9vbDE1NEVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTSIgKwogICAgICAiYXBTdHJpbmdCeXRlczE1NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2IiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJrXG4iICsKICAgICAgIlwwMzJGaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdCIgKwogICAgICAiXDAyMjxcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2UuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFN0IiArCiAgICAgICJyaW5nRml4ZWQzMjE1OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuXDAzMyIgKwogICAgICAiRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0IiArCiAgICAgICJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU3RyaW5nSW50IiArCiAgICAgICIzMjE2MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmVcblwwMzVGaWVsZE1hcFN0ciIgKwogICAgICAiaW5nTWVzc2FnZTE2M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMjNcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDEzMiQucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lcyIgKwogICAgICAic2FnZTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMkBcblwwMzZGaSIgKwogICAgICAiZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFN0cmluZ1NpIiArCiAgICAgICJudDMyMTY2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcCIgKwogICAgICAiU3RyaW5nU3RyaW5nMTY4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNCIgKwogICAgICAiRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDQ6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcFVpbnQzMkJvIiArCiAgICAgICJvbDE3MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTA6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbiIgKwogICAgICAidDMyRG91YmxlMTczRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJrXG5cMDMyRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyLS5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlc3RFbnVtOlwwMDI4XDAwMVwwMzI/IiArCiAgICAgICJcblwwMzVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFVpbnQzIiArCiAgICAgICIyRml4ZWQ2NDE3NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZCIgKwogICAgICAiTWFwVWludDMySW50MzIxNzhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFVpbnQzMkludDY0MTc5IiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJlXG4iICsKICAgICAgIlwwMzVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFxyXDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvM01lc3NhZ2U6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFVpbnQzMlNmIiArCiAgICAgICJpeGVkMzIxODFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMTc6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbCIgKwogICAgICAiZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyU2ludDY0IiArCiAgICAgICIxODRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMSIgKwogICAgICAiXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQiICsKICAgICAgIjMyVWludDMyMTg2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbCIgKwogICAgICAiZE1hcFVpbnQ2NEJvb2wxODhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDY0Qnl0ZXMxODkiICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuIiArCiAgICAgICJcMDM0RmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMya1xuXDAzMkZpZWxkTWFwVWludDY0RSIgKwogICAgICAibnVtMTkxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjI8XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIiArCiAgICAgICItLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlLlRlIiArCiAgICAgICJzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUYiICsKICAgICAgImllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFVpbnQ2NEZsIiArCiAgICAgICJvYXQxOTRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWkiICsKICAgICAgIm50NjRJbnQ2NDE5NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJlXG5cMDM1RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMjNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIkLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2U6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsIiArCiAgICAgICJkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwVWludDY0U2ZpeCIgKwogICAgICAiZWQ2NDE5OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMCIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwIiArCiAgICAgICJVaW50NjRTaW50NjQyMDFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI+XG5cMDM0IiArCiAgICAgICJGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDY0VWkiICsKICAgICAgIm50NjQyMDRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDQiICsKICAgICAgIjpcMDAyOFwwMDFCLFxuXDAzM2NvbS5nb29nbGUucHJvdG9idWYudGVzdGluZ0JcclBybyIgKwogICAgICAidG8zVGVzdGluZ2JcMDA2cHJvdG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM1NwZWNpYWxGaWVsZE5hbWVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM1NwZWNpYWxGaWVsZE5hbWVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM1NwZWNpYWxGaWVsZE5hbWVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlZ3VsYXJOYW1lIiwgIkNhY2hlZFNpemVfIiwgIlNlcmlhbGl6ZWRTaXplXyIsICJDbGFzc18iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGREb3VibGUxIiwgIkZpZWxkRmxvYXQyIiwgIkZpZWxkSW50NjQzIiwgIkZpZWxkVWludDY0NCIsICJGaWVsZEludDMyNSIsICJGaWVsZEZpeGVkNjQ2IiwgIkZpZWxkRml4ZWQzMjciLCAiRmllbGRCb29sOCIsICJGaWVsZFN0cmluZzkiLCAiRmllbGRNZXNzYWdlMTAiLCAiRmllbGRCeXRlczExIiwgIkZpZWxkVWludDMyMTIiLCAiRmllbGRFbnVtMTMiLCAiRmllbGRTZml4ZWQzMjE0IiwgIkZpZWxkU2ZpeGVkNjQxNSIsICJGaWVsZFNpbnQzMjE2IiwgIkZpZWxkU2ludDY0MTciLCAiRmllbGREb3VibGVMaXN0MTgiLCAiRmllbGRGbG9hdExpc3QxOSIsICJGaWVsZEludDY0TGlzdDIwIiwgIkZpZWxkVWludDY0TGlzdDIxIiwgIkZpZWxkSW50MzJMaXN0MjIiLCAiRmllbGRGaXhlZDY0TGlzdDIzIiwgIkZpZWxkRml4ZWQzMkxpc3QyNCIsICJGaWVsZEJvb2xMaXN0MjUiLCAiRmllbGRTdHJpbmdMaXN0MjYiLCAiRmllbGRNZXNzYWdlTGlzdDI3IiwgIkZpZWxkQnl0ZXNMaXN0MjgiLCAiRmllbGRVaW50MzJMaXN0MjkiLCAiRmllbGRFbnVtTGlzdDMwIiwgIkZpZWxkU2ZpeGVkMzJMaXN0MzEiLCAiRmllbGRTZml4ZWQ2NExpc3QzMiIsICJGaWVsZFNpbnQzMkxpc3QzMyIsICJGaWVsZFNpbnQ2NExpc3QzNCIsICJGaWVsZERvdWJsZUxpc3RQYWNrZWQzNSIsICJGaWVsZEZsb2F0TGlzdFBhY2tlZDM2IiwgIkZpZWxkSW50NjRMaXN0UGFja2VkMzciLCAiRmllbGRVaW50NjRMaXN0UGFja2VkMzgiLCAiRmllbGRJbnQzMkxpc3RQYWNrZWQzOSIsICJGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAiLCAiRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIiwgIkZpZWxkQm9vbExpc3RQYWNrZWQ0MiIsICJGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyIsICJGaWVsZEVudW1MaXN0UGFja2VkNDQiLCAiRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSIsICJGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IiwgIkZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IiwgIkZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IiwgIkZpZWxkRG91YmxlNTMiLCAiRmllbGRGbG9hdDU0IiwgIkZpZWxkSW50NjQ1NSIsICJGaWVsZFVpbnQ2NDU2IiwgIkZpZWxkSW50MzI1NyIsICJGaWVsZEZpeGVkNjQ1OCIsICJGaWVsZEZpeGVkMzI1OSIsICJGaWVsZEJvb2w2MCIsICJGaWVsZFN0cmluZzYxIiwgIkZpZWxkTWVzc2FnZTYyIiwgIkZpZWxkQnl0ZXM2MyIsICJGaWVsZFVpbnQzMjY0IiwgIkZpZWxkU2ZpeGVkMzI2NSIsICJGaWVsZFNmaXhlZDY0NjYiLCAiRmllbGRTaW50MzI2NyIsICJGaWVsZFNpbnQ2NDY4IiwgIlRlc3RPbmVvZiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNFbXB0eV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZE1hcEJvb2xCb29sMSIsICJGaWVsZE1hcEJvb2xCeXRlczIiLCAiRmllbGRNYXBCb29sRG91YmxlMyIsICJGaWVsZE1hcEJvb2xFbnVtNCIsICJGaWVsZE1hcEJvb2xGaXhlZDMyNSIsICJGaWVsZE1hcEJvb2xGaXhlZDY0NiIsICJGaWVsZE1hcEJvb2xGbG9hdDciLCAiRmllbGRNYXBCb29sSW50MzI4IiwgIkZpZWxkTWFwQm9vbEludDY0OSIsICJGaWVsZE1hcEJvb2xNZXNzYWdlMTAiLCAiRmllbGRNYXBCb29sU2ZpeGVkMzIxMSIsICJGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyIiwgIkZpZWxkTWFwQm9vbFNpbnQzMjEzIiwgIkZpZWxkTWFwQm9vbFNpbnQ2NDE0IiwgIkZpZWxkTWFwQm9vbFN0cmluZzE1IiwgIkZpZWxkTWFwQm9vbFVpbnQzMjE2IiwgIkZpZWxkTWFwQm9vbFVpbnQ2NDE3IiwgIkZpZWxkTWFwRml4ZWQzMkJvb2wxOCIsICJGaWVsZE1hcEZpeGVkMzJCeXRlczE5IiwgIkZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwIiwgIkZpZWxkTWFwRml4ZWQzMkVudW0yMSIsICJGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIiLCAiRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzIiwgIkZpZWxkTWFwRml4ZWQzMkZsb2F0MjQiLCAiRmllbGRNYXBGaXhlZDMySW50MzIyNSIsICJGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2IiwgIkZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNyIsICJGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4IiwgIkZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkiLCAiRmllbGRNYXBGaXhlZDMyU2ludDMyMzAiLCAiRmllbGRNYXBGaXhlZDMyU2ludDY0MzEiLCAiRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIiLCAiRmllbGRNYXBGaXhlZDMyVWludDMyMzMiLCAiRmllbGRNYXBGaXhlZDMyVWludDY0MzQiLCAiRmllbGRNYXBGaXhlZDY0Qm9vbDM1IiwgIkZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYiLCAiRmllbGRNYXBGaXhlZDY0RG91YmxlMzciLCAiRmllbGRNYXBGaXhlZDY0RW51bTM4IiwgIkZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSIsICJGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAiLCAiRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSIsICJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyIiwgIkZpZWxkTWFwRml4ZWQ2NEludDY0NDMiLCAiRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0IiwgIkZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUiLCAiRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NiIsICJGaWVsZE1hcEZpeGVkNjRTaW50MzI0NyIsICJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCIsICJGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSIsICJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCIsICJGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSIsICJGaWVsZE1hcEludDMyQm9vbDUyIiwgIkZpZWxkTWFwSW50MzJCeXRlczUzIiwgIkZpZWxkTWFwSW50MzJEb3VibGU1NCIsICJGaWVsZE1hcEludDMyRW51bTU1IiwgIkZpZWxkTWFwSW50MzJGaXhlZDMyNTYiLCAiRmllbGRNYXBJbnQzMkZpeGVkNjQ1NyIsICJGaWVsZE1hcEludDMyRmxvYXQ1OCIsICJGaWVsZE1hcEludDMySW50MzI1OSIsICJGaWVsZE1hcEludDMySW50NjQ2MCIsICJGaWVsZE1hcEludDMyTWVzc2FnZTYxIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQzMjYyIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzIiwgIkZpZWxkTWFwSW50MzJTaW50MzI2NCIsICJGaWVsZE1hcEludDMyU2ludDY0NjUiLCAiRmllbGRNYXBJbnQzMlN0cmluZzY2IiwgIkZpZWxkTWFwSW50MzJVaW50MzI2NyIsICJGaWVsZE1hcEludDMyVWludDY0NjgiLCAiRmllbGRNYXBJbnQ2NEJvb2w2OSIsICJGaWVsZE1hcEludDY0Qnl0ZXM3MCIsICJGaWVsZE1hcEludDY0RG91YmxlNzEiLCAiRmllbGRNYXBJbnQ2NEVudW03MiIsICJGaWVsZE1hcEludDY0Rml4ZWQzMjczIiwgIkZpZWxkTWFwSW50NjRGaXhlZDY0NzQiLCAiRmllbGRNYXBJbnQ2NEZsb2F0NzUiLCAiRmllbGRNYXBJbnQ2NEludDMyNzYiLCAiRmllbGRNYXBJbnQ2NEludDY0NzciLCAiRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCIsICJGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSIsICJGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCIsICJGaWVsZE1hcEludDY0U2ludDMyODEiLCAiRmllbGRNYXBJbnQ2NFNpbnQ2NDgyIiwgIkZpZWxkTWFwSW50NjRTdHJpbmc4MyIsICJGaWVsZE1hcEludDY0VWludDMyODQiLCAiRmllbGRNYXBJbnQ2NFVpbnQ2NDg1IiwgIkZpZWxkTWFwU2ZpeGVkMzJCb29sODYiLCAiRmllbGRNYXBTZml4ZWQzMkJ5dGVzODciLCAiRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4IiwgIkZpZWxkTWFwU2ZpeGVkMzJFbnVtODkiLCAiRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCIsICJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxIiwgIkZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0IiwgIkZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTciLCAiRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4IiwgIkZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSIsICJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwIiwgIkZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEiLCAiRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMiIsICJGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMyIsICJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQiLCAiRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSIsICJGaWVsZE1hcFNmaXhlZDY0RW51bTEwNiIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNyIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCIsICJGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkiLCAiRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwIiwgIkZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSIsICJGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMiIsICJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMiLCAiRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0IiwgIkZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUiLCAiRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNiIsICJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3IiwgIkZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgiLCAiRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSIsICJGaWVsZE1hcFNpbnQzMkJvb2wxMjAiLCAiRmllbGRNYXBTaW50MzJCeXRlczEyMSIsICJGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMiIsICJGaWVsZE1hcFNpbnQzMkVudW0xMjMiLCAiRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0IiwgIkZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSIsICJGaWVsZE1hcFNpbnQzMkZsb2F0MTI2IiwgIkZpZWxkTWFwU2ludDMySW50MzIxMjciLCAiRmllbGRNYXBTaW50MzJJbnQ2NDEyOCIsICJGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkiLCAiRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCIsICJGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxIiwgIkZpZWxkTWFwU2ludDMyU2ludDMyMTMyIiwgIkZpZWxkTWFwU2ludDMyU2ludDY0MTMzIiwgIkZpZWxkTWFwU2ludDMyU3RyaW5nMTM0IiwgIkZpZWxkTWFwU2ludDMyVWludDMyMTM1IiwgIkZpZWxkTWFwU2ludDMyVWludDY0MTM2IiwgIkZpZWxkTWFwU2ludDY0Qm9vbDEzNyIsICJGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4IiwgIkZpZWxkTWFwU2ludDY0RG91YmxlMTM5IiwgIkZpZWxkTWFwU2ludDY0RW51bTE0MCIsICJGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEiLCAiRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyIiwgIkZpZWxkTWFwU2ludDY0RmxvYXQxNDMiLCAiRmllbGRNYXBTaW50NjRJbnQzMjE0NCIsICJGaWVsZE1hcFNpbnQ2NEludDY0MTQ1IiwgIkZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NiIsICJGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3IiwgIkZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgiLCAiRmllbGRNYXBTaW50NjRTaW50MzIxNDkiLCAiRmllbGRNYXBTaW50NjRTaW50NjQxNTAiLCAiRmllbGRNYXBTaW50NjRTdHJpbmcxNTEiLCAiRmllbGRNYXBTaW50NjRVaW50MzIxNTIiLCAiRmllbGRNYXBTaW50NjRVaW50NjQxNTMiLCAiRmllbGRNYXBTdHJpbmdCb29sMTU0IiwgIkZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUiLCAiRmllbGRNYXBTdHJpbmdEb3VibGUxNTYiLCAiRmllbGRNYXBTdHJpbmdFbnVtMTU3IiwgIkZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCIsICJGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkiLCAiRmllbGRNYXBTdHJpbmdGbG9hdDE2MCIsICJGaWVsZE1hcFN0cmluZ0ludDMyMTYxIiwgIkZpZWxkTWFwU3RyaW5nSW50NjQxNjIiLCAiRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzIiwgIkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQiLCAiRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSIsICJGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NiIsICJGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NyIsICJGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCIsICJGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSIsICJGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCIsICJGaWVsZE1hcFVpbnQzMkJvb2wxNzEiLCAiRmllbGRNYXBVaW50MzJCeXRlczE3MiIsICJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MyIsICJGaWVsZE1hcFVpbnQzMkVudW0xNzQiLCAiRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1IiwgIkZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NiIsICJGaWVsZE1hcFVpbnQzMkZsb2F0MTc3IiwgIkZpZWxkTWFwVWludDMySW50MzIxNzgiLCAiRmllbGRNYXBVaW50MzJJbnQ2NDE3OSIsICJGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAiLCAiRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSIsICJGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyIiwgIkZpZWxkTWFwVWludDMyU2ludDMyMTgzIiwgIkZpZWxkTWFwVWludDMyU2ludDY0MTg0IiwgIkZpZWxkTWFwVWludDMyU3RyaW5nMTg1IiwgIkZpZWxkTWFwVWludDMyVWludDMyMTg2IiwgIkZpZWxkTWFwVWludDMyVWludDY0MTg3IiwgIkZpZWxkTWFwVWludDY0Qm9vbDE4OCIsICJGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5IiwgIkZpZWxkTWFwVWludDY0RG91YmxlMTkwIiwgIkZpZWxkTWFwVWludDY0RW51bTE5MSIsICJGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIiLCAiRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzIiwgIkZpZWxkTWFwVWludDY0RmxvYXQxOTQiLCAiRmllbGRNYXBVaW50NjRJbnQzMjE5NSIsICJGaWVsZE1hcFVpbnQ2NEludDY0MTk2IiwgIkZpZWxkTWFwVWludDY0TWVzc2FnZTE5NyIsICJGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4IiwgIkZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkiLCAiRmllbGRNYXBVaW50NjRTaW50MzIyMDAiLCAiRmllbGRNYXBVaW50NjRTaW50NjQyMDEiLCAiRmllbGRNYXBVaW50NjRTdHJpbmcyMDIiLCAiRmllbGRNYXBVaW50NjRVaW50MzIyMDMiLCAiRmllbGRNYXBVaW50NjRVaW50NjQyMDQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQm9vbDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sQnl0ZXMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEVudW00RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50MzI4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkMzIxMUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sU3RyaW5nMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDMyMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDMyMzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCb29sMzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDM4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RmxvYXQ0MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0SW50NjQ0M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDY0NTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQzMjU2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDY1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDMyNjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDMyNzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0U3RyaW5nODNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTA0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDExMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCb29sMTIwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJFbnVtMTIzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTMwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTM3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEVudW0xNDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQ3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTY0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTcxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJFbnVtMTc0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTg4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTkzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQDel3RqgVkvAIFZLwAyAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL1Byb3RvM1Rlc3RpbmdMaXRlLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8zX21lc3NhZ2VfbGl0ZS5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nOwoKcHVibGljIGZpbmFsIGNsYXNzIFByb3RvM1Rlc3RpbmdMaXRlIHsKICBwcml2YXRlIFByb3RvM1Rlc3RpbmdMaXRlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGUxLgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGREb3VibGUxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0Mi4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRGbG9hdDIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQzLgogICAgICovCiAgICBsb25nIGdldEZpZWxkSW50NjQzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFVpbnQ2NDQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzI1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMjUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ2LgogICAgICovCiAgICBsb25nIGdldEZpZWxkRml4ZWQ2NDYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI3LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyNygpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbDguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sOCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmc5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlMTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTEwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNZXNzYWdlMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlMTBPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlczExLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzIxMi4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyMTIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtMTMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEVudW0xM1ZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bTEzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtMTMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMjE0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMjE0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQxNS4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0MTUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMjE2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50MzIxNigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0MTcuCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZERvdWJsZUxpc3QxOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3QxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZERvdWJsZUxpc3QxOChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3QxOS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdExpc3QxOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0MTkoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdDIwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQ2NExpc3QyMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3QyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3QyMChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdDIxLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0MjEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkVWludDY0TGlzdDIxKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAqLwogICAgaW50IGdldEZpZWxkSW50MzJMaXN0MjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0MjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRml4ZWQ2NExpc3QyMy4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdDIzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3QyNS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3QyNS4KICAgICAqLwogICAgaW50IGdldEZpZWxkQm9vbExpc3QyNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbExpc3QyNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTdHJpbmdMaXN0MjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nTGlzdDI2KGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiAKICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCeXRlc0xpc3QyOC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCeXRlc0xpc3QyOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzTGlzdDI4KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0MjkuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3QyOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMkxpc3QyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMkxpc3QyOShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0MzBMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEVudW1MaXN0MzAuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEVudW1MaXN0MzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0MzAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRFbnVtTGlzdDMwVmFsdWVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgZmllbGRFbnVtTGlzdDMwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRW51bUxpc3QzMFZhbHVlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkNjRMaXN0MzIuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50MzJMaXN0MzMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMkxpc3QzMyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdDM0LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjRMaXN0MzQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ludDY0TGlzdDM0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAqLwogICAgaW50IGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0UGFja2VkMzcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzgoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdFBhY2tlZDQyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDQoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRWYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBmaWVsZEVudW1MaXN0UGFja2VkNDQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0VmFsdWUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDgoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlNTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRG91YmxlNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV81MyA9IDUzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlNTMuCiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZERvdWJsZTUzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdDU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZsb2F0NTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0NTQuCiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkRmxvYXQ1NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50NjQ1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRJbnQ2NDU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NDU1LgogICAgICovCiAgICBsb25nIGdldEZpZWxkSW50NjQ1NSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50NjQ1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRVaW50NjQ1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQ1Ni4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFVpbnQ2NDU2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMjU3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEludDMyNTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZEludDMyNTcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDY0NTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRml4ZWQ2NDU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDU4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkRml4ZWQ2NDU4KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQzMjU5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEZpeGVkMzI1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI1OS4KICAgICAqLwogICAgaW50IGdldEZpZWxkRml4ZWQzMjU5KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQm9vbDYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJvb2w2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2w2MC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZEJvb2w2MCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTdHJpbmc2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRTdHJpbmc2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmc2MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc2MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmc2MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWVzc2FnZTYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2U2Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWVzc2FnZTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTYyT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCeXRlczYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkVWludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFVpbnQzMjY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDMyNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyNjUuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNmaXhlZDMyNjUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDY0NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkNjQ2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQ2Ni4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZFNmaXhlZDY0NjYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDMyNjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkU2ludDMyNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyNjcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZFNpbnQzMjY3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQ2NDY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFNpbnQ2NDY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NDY4LgogICAgICovCiAgICBsb25nIGdldEZpZWxkU2ludDY0NjgoKTsKCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdE9uZW9mQ2FzZSBnZXRUZXN0T25lb2ZDYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvM01lc3NhZ2VMaXRlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSkKICAgICAgUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvM01lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFByb3RvM01lc3NhZ2VMaXRlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUHJvdG8zTWVzc2FnZUxpdGUoKSB7CiAgICAgIGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgICAgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgZmllbGRFbnVtMTNfID0gMDsKICAgICAgZmllbGREb3VibGVMaXN0MThfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZEJvb2xMaXN0MjVfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gZW1wdHlMb25nTGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFByb3RvM01lc3NhZ2VMaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBUZXN0RW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlpFUk8gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFpFUk8oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5PTkUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIE9ORSgxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRXTyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgVFdPKDIpLAogICAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWkVST19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5PTkUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORV9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5UV08gPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRXT19WQUxVRSA9IDI7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gWkVSTzsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIE9ORTsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIFRXTzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgVGVzdEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFRlc3RFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBUZXN0RW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBkZXNjcmlwdG9yIG9mIGFuIHVucmVjb2duaXplZCBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgVGVzdEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0pCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHByaXZhdGUgaW50IHRlc3RPbmVvZkNhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHRlc3RPbmVvZl87CiAgICBwdWJsaWMgZW51bSBUZXN0T25lb2ZDYXNlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICAgIEZJRUxEX0RPVUJMRV81Myg1MyksCiAgICAgIEZJRUxEX0ZMT0FUXzU0KDU0KSwKICAgICAgRklFTERfSU5UNjRfNTUoNTUpLAogICAgICBGSUVMRF9VSU5UNjRfNTYoNTYpLAogICAgICBGSUVMRF9JTlQzMl81Nyg1NyksCiAgICAgIEZJRUxEX0ZJWEVENjRfNTgoNTgpLAogICAgICBGSUVMRF9GSVhFRDMyXzU5KDU5KSwKICAgICAgRklFTERfQk9PTF82MCg2MCksCiAgICAgIEZJRUxEX1NUUklOR182MSg2MSksCiAgICAgIEZJRUxEX01FU1NBR0VfNjIoNjIpLAogICAgICBGSUVMRF9CWVRFU182Myg2MyksCiAgICAgIEZJRUxEX1VJTlQzMl82NCg2NCksCiAgICAgIEZJRUxEX1NGSVhFRDMyXzY1KDY1KSwKICAgICAgRklFTERfU0ZJWEVENjRfNjYoNjYpLAogICAgICBGSUVMRF9TSU5UMzJfNjcoNjcpLAogICAgICBGSUVMRF9TSU5UNjRfNjgoNjgpLAogICAgICBURVNUT05FT0ZfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgVGVzdE9uZW9mQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RPbmVvZkNhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBUZXN0T25lb2ZDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDUzOiByZXR1cm4gRklFTERfRE9VQkxFXzUzOwogICAgICAgICAgY2FzZSA1NDogcmV0dXJuIEZJRUxEX0ZMT0FUXzU0OwogICAgICAgICAgY2FzZSA1NTogcmV0dXJuIEZJRUxEX0lOVDY0XzU1OwogICAgICAgICAgY2FzZSA1NjogcmV0dXJuIEZJRUxEX1VJTlQ2NF81NjsKICAgICAgICAgIGNhc2UgNTc6IHJldHVybiBGSUVMRF9JTlQzMl81NzsKICAgICAgICAgIGNhc2UgNTg6IHJldHVybiBGSUVMRF9GSVhFRDY0XzU4OwogICAgICAgICAgY2FzZSA1OTogcmV0dXJuIEZJRUxEX0ZJWEVEMzJfNTk7CiAgICAgICAgICBjYXNlIDYwOiByZXR1cm4gRklFTERfQk9PTF82MDsKICAgICAgICAgIGNhc2UgNjE6IHJldHVybiBGSUVMRF9TVFJJTkdfNjE7CiAgICAgICAgICBjYXNlIDYyOiByZXR1cm4gRklFTERfTUVTU0FHRV82MjsKICAgICAgICAgIGNhc2UgNjM6IHJldHVybiBGSUVMRF9CWVRFU182MzsKICAgICAgICAgIGNhc2UgNjQ6IHJldHVybiBGSUVMRF9VSU5UMzJfNjQ7CiAgICAgICAgICBjYXNlIDY1OiByZXR1cm4gRklFTERfU0ZJWEVEMzJfNjU7CiAgICAgICAgICBjYXNlIDY2OiByZXR1cm4gRklFTERfU0ZJWEVENjRfNjY7CiAgICAgICAgICBjYXNlIDY3OiByZXR1cm4gRklFTERfU0lOVDMyXzY3OwogICAgICAgICAgY2FzZSA2ODogcmV0dXJuIEZJRUxEX1NJTlQ2NF82ODsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFRFU1RPTkVPRl9OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBUZXN0T25lb2ZDYXNlCiAgICBnZXRUZXN0T25lb2ZDYXNlKCkgewogICAgICByZXR1cm4gVGVzdE9uZW9mQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFXzFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgZG91YmxlIGZpZWxkRG91YmxlMV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGUxKCkgewogICAgICByZXR1cm4gZmllbGREb3VibGUxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF8yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGZsb2F0IGZpZWxkRmxvYXQyXyA9IDBGOwogICAgLyoqCiAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXQyKCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdDJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDY0XzNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgbG9uZyBmaWVsZEludDY0M18gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjQzKCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NDNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQ2NF80X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGxvbmcgZmllbGRVaW50NjQ0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjQ0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjQ0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQzMl81X0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIGludCBmaWVsZEludDMyNV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNSgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzI1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDY0XzZfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgbG9uZyBmaWVsZEZpeGVkNjQ2XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0NigpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NDZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVEMzJfN19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBpbnQgZmllbGRGaXhlZDMyN18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzI3KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyN187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF84X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIGJvb2xlYW4gZmllbGRCb29sOF8gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbDgoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2w4XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TVFJJTkdfOV9GSUVMRF9OVU1CRVIgPSA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgZmllbGRTdHJpbmc5XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkU3RyaW5nOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBmaWVsZFN0cmluZzlfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBmaWVsZFN0cmluZzlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUVTU0FHRV8xMF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkTWVzc2FnZTEwXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1lc3NhZ2UxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTWVzc2FnZTEwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTEwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWVzc2FnZTEwKCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZE1lc3NhZ2UxMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2UxME9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNZXNzYWdlMTBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JZVEVTXzExX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCkgewogICAgICByZXR1cm4gZmllbGRCeXRlczExXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9VSU5UMzJfMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIGludCBmaWVsZFVpbnQzMjEyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMjEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyMTIoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMjEyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9FTlVNXzEzX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgcHJpdmF0ZSBpbnQgZmllbGRFbnVtMTNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW0xMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldEZpZWxkRW51bTEzVmFsdWUoKSB7CiAgICAgIHJldHVybiBmaWVsZEVudW0xM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bTEzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtMTMoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKGZpZWxkRW51bTEzXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSID0gMTQ7CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDMyMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMjE0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQzMjE0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQ2NF8xNV9GSUVMRF9OVU1CRVIgPSAxNTsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFNmaXhlZDY0MTVfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NDE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgaW50IGZpZWxkU2ludDMyMTZfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyMTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzIxNigpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyMTZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF8xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIHByaXZhdGUgbG9uZyBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0MTdfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0RPVUJMRV9MSVNUXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3QxOF8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0MTguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGREb3VibGVMaXN0MThDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3QxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0MTgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GTE9BVF9MSVNUXzE5X0ZJRUxEX05VTUJFUiA9IDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IGZpZWxkRmxvYXRMaXN0MTlfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0MTkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0MTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3QxOShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9JTlQ2NF9MSVNUXzIwX0ZJRUxEX05VTUJFUiA9IDIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRJbnQ2NExpc3QyMF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3QyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50NjRMaXN0MjAuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3QyMENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0XzIwID0gMjAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0MjAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3QyMF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfMjFfRklFTERfTlVNQkVSID0gMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFVpbnQ2NExpc3QyMV8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkVWludDY0TGlzdDIxTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQ2NExpc3QyMS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQ2NExpc3QyMUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0TGlzdDIxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfTElTVF8yMl9GSUVMRF9OVU1CRVIgPSAyMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRJbnQzMkxpc3QyMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdDIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQzMkxpc3QyMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdDIyQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfMjIgPSAyMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3QyMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0MjJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRklYRUQ2NF9MSVNUXzIzX0ZJRUxEX05VTUJFUiA9IDIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRGaXhlZDY0TGlzdDIzXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdDIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRGaXhlZDY0TGlzdDIzTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdDIzQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdDIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdDIzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdDIzXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyX0xJU1RfMjRfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkRml4ZWQzMkxpc3QyNF8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdDI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3QyNF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0MjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQk9PTF9MSVNUXzI1X0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdDI1XyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3QyNV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEJvb2xMaXN0MjUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdDI1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdDI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1Xy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TVFJJTkdfTElTVF8yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZmllbGRTdHJpbmdMaXN0MjZfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTdHJpbmdMaXN0MjYuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFN0cmluZ0xpc3QyNi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmdMaXN0MjYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZmllbGRTdHJpbmdMaXN0MjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NRVNTQUdFX0xJU1RfMjdfRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1lc3NhZ2VMaXN0MjdfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWVzc2FnZUxpc3QyN0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNZXNzYWdlTGlzdDI3KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU19MSVNUXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRCeXRlc0xpc3QyOF8gPQogICAgICAgIGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQnl0ZXNMaXN0MjguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXNMaXN0MjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkQnl0ZXNMaXN0MjgoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9MSVNUXzI5X0ZJRUxEX05VTUJFUiA9IDI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFVpbnQzMkxpc3QyOV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdDI5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0MjkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdDI5KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0MjlfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRU5VTV9MSVNUXzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZEVudW1MaXN0MzBfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRW51bUxpc3QzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZ2V0RmllbGRFbnVtTGlzdDMwTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdDMwXywgZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3QzMENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRFbnVtTGlzdDMwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwX2NvbnZlcnRlcl8uY29udmVydChmaWVsZEVudW1MaXN0MzBfLmdldChpbmRleCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdDMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZEVudW1MaXN0MzBWYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0MzBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIGZpZWxkRW51bUxpc3QzMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRFbnVtTGlzdDMwVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0MzBfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVEMzJfTElTVF8zMV9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTZml4ZWQzMkxpc3QzMV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF8zMSA9IDMxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3QzMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfTElTVF8zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF8zMiA9IDMyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0TGlzdDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl9MSVNUXzMzX0ZJRUxEX05VTUJFUiA9IDMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFNpbnQzMkxpc3QzM18gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0MzNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdDMzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyTGlzdDMzQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzJMaXN0MzMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyTGlzdDMzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0MzNfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0X0xJU1RfMzRfRklFTERfTlVNQkVSID0gMzQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3QzNF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdDM0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3QzNENvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdDM0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjRMaXN0MzQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFX0xJU1RfUEFDS0VEXzM1X0ZJRUxEX05VTUJFUiA9IDM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGREb3VibGVMaXN0UGFja2VkMzUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUX0xJU1RfUEFDS0VEXzM2X0ZJRUxEX05VTUJFUiA9IDM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkRmxvYXRMaXN0UGFja2VkMzZNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfTElTVF9QQUNLRURfMzdfRklFTERfTlVNQkVSID0gMzc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDY0TGlzdFBhY2tlZDM3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF9wYWNrZWRfMzcgPSAzNyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzcoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0xJU1RfUEFDS0VEXzM4X0ZJRUxEX05VTUJFUiA9IDM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0UGFja2VkMzguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfTElTVF9QQUNLRURfMzlfRklFTERfTlVNQkVSID0gMzk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50MzJMaXN0UGFja2VkMzkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0X3BhY2tlZF8zOSA9IDM5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzkoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRJbnQzMkxpc3RQYWNrZWQzOU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDY0X0xJU1RfUEFDS0VEXzQwX0ZJRUxEX05VTUJFUiA9IDQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwQ291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9GSVhFRDMyX0xJU1RfUEFDS0VEXzQxX0ZJRUxEX05VTUJFUiA9IDQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0JPT0xfTElTVF9QQUNLRURfNDJfRklFTERfTlVNQkVSID0gNDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBmaWVsZEJvb2xMaXN0UGFja2VkNDJfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJvb2xMaXN0UGFja2VkNDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2xMaXN0UGFja2VkNDIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRCb29sTGlzdFBhY2tlZDQyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9MSVNUX1BBQ0tFRF80M19GSUVMRF9OVU1CRVIgPSA0MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzTGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0My4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRVaW50MzJMaXN0UGFja2VkNDNNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRU5VTV9MSVNUX1BBQ0tFRF80NF9GSUVMRF9OVU1CRVIgPSA0NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0XzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+KGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8sIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF9jb252ZXJ0ZXJfLmNvbnZlcnQoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3RQYWNrZWQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0VmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBmaWVsZEVudW1MaXN0UGFja2VkNDQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRFbnVtTGlzdFBhY2tlZDQ0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl9MSVNUX1BBQ0tFRF80NV9GSUVMRF9OVU1CRVIgPSA0NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NSA9IDQ1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSB7CiAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NGSVhFRDY0X0xJU1RfUEFDS0VEXzQ2X0ZJRUxEX05VTUJFUiA9IDQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NkNvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0X3BhY2tlZF80NiA9IDQ2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQzMl9MSVNUX1BBQ0tFRF80N19GSUVMRF9OVU1CRVIgPSA0NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3TGlzdCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0Ny4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgewogICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50MzJMaXN0UGFja2VkNDdNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDY0X0xJU1RfUEFDS0VEXzQ4X0ZJRUxEX05VTUJFUiA9IDQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKSB7CiAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTaW50NjRMaXN0UGFja2VkNDguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhDb3VudCgpIHsKICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCkgewogICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50NjRMaXN0UGFja2VkNDhNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRE9VQkxFXzUzX0ZJRUxEX05VTUJFUiA9IDUzOwogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGREb3VibGU1MygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDUzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGU1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTUzKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTMpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Eb3VibGUpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBEOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZMT0FUXzU0X0ZJRUxEX05VTUJFUiA9IDU0OwogICAgLyoqCiAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdDU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGbG9hdDU0KCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNTQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDU0KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTQpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5GbG9hdCkgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEY7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfNTVfRklFTERfTlVNQkVSID0gNTU7CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDY0NTUoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjQ1NSgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU1KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0XzU2X0ZJRUxEX05VTUJFUiA9IDU2OwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NDU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50NjQ1NigpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQ1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UMzJfNTdfRklFTERfTlVNQkVSID0gNTc7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyNTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTcoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMjU3KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVENjRfNThfRklFTERfTlVNQkVSID0gNTg7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDY0NTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU4OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0NTgoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBMOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJWEVEMzJfNTlfRklFTERfTlVNQkVSID0gNTk7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDMyNTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU5OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzI1OSgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MXzYwX0ZJRUxEX05VTUJFUiA9IDYwOwogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfNjAgPSA2MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQm9vbDYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCb29sNjAoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbDYwKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Cb29sZWFuKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TVFJJTkdfNjFfRklFTERfTlVNQkVSID0gNjE7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZzYxKCkgewogICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZzYxLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzYxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nNjEuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGaWVsZFN0cmluZzYxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIHJlZiA9IHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01FU1NBR0VfNjJfRklFTERfTlVNQkVSID0gNjI7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlNjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDYyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1lc3NhZ2U2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2U2Mk9yQnVpbGRlcigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfQllURVNfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzNjMoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczYzKCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjMpIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDMyNjQoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzI2NCgpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9TRklYRUQzMl82NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ZpeGVkMzI2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzI2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyNjUoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0ZJWEVENjRfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDY0NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ZpeGVkNjQ2NigpIHsKICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY2KSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMEw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfU0lOVDMyXzY3X0ZJRUxEX05VTUJFUiA9IDY3OwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNpbnQzMjY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50MzI2NygpIHsKICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDY3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzI2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMjY3KCkgewogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NJTlQ2NF82OF9GSUVMRF9OVU1CRVIgPSA2ODsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50NjQ2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ludDY0NjgoKSB7CiAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2ODsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0NjgoKSB7CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OCkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgIH0KICAgICAgcmV0dXJuIDBMOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhmaWVsZERvdWJsZTFfKSAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEsIGZpZWxkRG91YmxlMV8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZmllbGRGbG9hdDJfKSAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMiwgZmllbGRGbG9hdDJfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRJbnQ2NDNfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMywgZmllbGRJbnQ2NDNfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRVaW50NjQ0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCBmaWVsZFVpbnQ2NDRfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRJbnQzMjVfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1LCBmaWVsZEludDMyNV8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEZpeGVkNjQ2XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoNiwgZmllbGRGaXhlZDY0Nl8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEZpeGVkMzI3XyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMig3LCBmaWVsZEZpeGVkMzI3Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkQm9vbDhfICE9IGZhbHNlKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCg4LCBmaWVsZEJvb2w4Xyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KGZpZWxkU3RyaW5nOV8pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA5LCBmaWVsZFN0cmluZzlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCBnZXRGaWVsZE1lc3NhZ2UxMCgpKTsKICAgICAgfQogICAgICBpZiAoIWZpZWxkQnl0ZXMxMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMTEsIGZpZWxkQnl0ZXMxMV8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFVpbnQzMjEyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDEyLCBmaWVsZFVpbnQzMjEyXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkRW51bTEzXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTMsIGZpZWxkRW51bTEzXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkU2ZpeGVkMzIxNF8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDE0LCBmaWVsZFNmaXhlZDMyMTRfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRTZml4ZWQ2NDE1XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDE1LCBmaWVsZFNmaXhlZDY0MTVfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRTaW50MzIxNl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMigxNiwgZmllbGRTaW50MzIxNl8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFNpbnQ2NDE3XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgxNywgZmllbGRTaW50NjQxN18pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGREb3VibGVMaXN0MThfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDE4LCBmaWVsZERvdWJsZUxpc3QxOF8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRmxvYXRMaXN0MTlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTksIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0MjBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMjAsIGZpZWxkSW50NjRMaXN0MjBfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50NjRMaXN0MjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDIxLCBmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdDIyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIyLCBmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDY0TGlzdDIzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoMjMsIGZpZWxkRml4ZWQ2NExpc3QyM18uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMigyNCwgZmllbGRGaXhlZDMyTGlzdDI0Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCb29sTGlzdDI1Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMjUsIGZpZWxkQm9vbExpc3QyNV8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFN0cmluZ0xpc3QyNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI2LCBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI3LCBmaWVsZE1lc3NhZ2VMaXN0MjdfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEJ5dGVzTGlzdDI4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDI4LCBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0MjlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDI5LCBmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3QzMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDMwLCBmaWVsZEVudW1MaXN0MzBfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDMxLCBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTZml4ZWQ2NExpc3QzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgzMiwgZmllbGRTZml4ZWQ2NExpc3QzMl8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3QzM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoMzMsIGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDM0LCBmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyODIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGVOb1RhZyhmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjkwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEZsb2F0TGlzdFBhY2tlZDM2TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcoZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyOTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMwNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NE5vVGFnKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzE0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEludDMyTGlzdFBhY2tlZDM5TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcoZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyhmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkQm9vbExpc3RQYWNrZWQ0Mk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2xOb1RhZyhmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzU0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZEVudW1MaXN0UGFja2VkNDRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM3OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoZmllbGRTaW50MzJMaXN0UGFja2VkNDdNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzg2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcoZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgKICAgICAgICAgICAgNTMsIChkb3VibGUpKChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoCiAgICAgICAgICAgIDU0LCAoZmxvYXQpKChqYXZhLmxhbmcuRmxvYXQpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgKICAgICAgICAgICAgNTUsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoCiAgICAgICAgICAgIDU2LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDU3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KAogICAgICAgICAgICA1OCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1OSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoCiAgICAgICAgICAgIDU5LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKAogICAgICAgICAgICA2MCwgKGJvb2xlYW4pKChqYXZhLmxhbmcuQm9vbGVhbikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNjEsIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNjIsIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKAogICAgICAgICAgICA2MywgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKAogICAgICAgICAgICA2NCwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY1KSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoCiAgICAgICAgICAgIDY1LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjYpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgKICAgICAgICAgICAgNjYsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoCiAgICAgICAgICAgIDY3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoCiAgICAgICAgICAgIDY4LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMoZmllbGREb3VibGUxXykgIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDEsIGZpZWxkRG91YmxlMV8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZmllbGRGbG9hdDJfKSAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgyLCBmaWVsZEZsb2F0Ml8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZEludDY0M18gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDMsIGZpZWxkSW50NjQzXyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkVWludDY0NF8gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZSg0LCBmaWVsZFVpbnQ2NDRfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRJbnQzMjVfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUsIGZpZWxkSW50MzI1Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkRml4ZWQ2NDZfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKDYsIGZpZWxkRml4ZWQ2NDZfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRGaXhlZDMyN18gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSg3LCBmaWVsZEZpeGVkMzI3Xyk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkQm9vbDhfICE9IGZhbHNlKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDgsIGZpZWxkQm9vbDhfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkoZmllbGRTdHJpbmc5XykpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDksIGZpZWxkU3RyaW5nOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZ2V0RmllbGRNZXNzYWdlMTAoKSk7CiAgICAgIH0KICAgICAgaWYgKCFmaWVsZEJ5dGVzMTFfLmlzRW1wdHkoKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoMTEsIGZpZWxkQnl0ZXMxMV8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFVpbnQzMjEyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMTIsIGZpZWxkVWludDMyMTJfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRFbnVtMTNfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEzLCBmaWVsZEVudW0xM18pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFNmaXhlZDMyMTRfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkMzJTaXplKDE0LCBmaWVsZFNmaXhlZDMyMTRfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRTZml4ZWQ2NDE1XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQ2NFNpemUoMTUsIGZpZWxkU2ZpeGVkNjQxNV8pOwogICAgICB9CiAgICAgIGlmIChmaWVsZFNpbnQzMjE2XyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoMTYsIGZpZWxkU2ludDMyMTZfKTsKICAgICAgfQogICAgICBpZiAoZmllbGRTaW50NjQxN18gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSgxNywgZmllbGRTaW50NjQxN18pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQ2NExpc3QyMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhmaWVsZEludDY0TGlzdDIwXy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhmaWVsZFVpbnQ2NExpc3QyMV8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhmaWVsZEludDMyTGlzdDIyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkSW50MzJMaXN0MjJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldEZpZWxkQm9vbExpc3QyNUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTdHJpbmdMaXN0MjZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjcsIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGkpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkQnl0ZXNMaXN0MjhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcoZmllbGRCeXRlc0xpc3QyOF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkVWludDMyTGlzdDI5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhmaWVsZFVpbnQzMkxpc3QyOV8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFVpbnQzMkxpc3QyOUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEVudW1MaXN0MzBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhmaWVsZEVudW1MaXN0MzBfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZmllbGRFbnVtTGlzdDMwXy5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKGZpZWxkU2ludDMyTGlzdDMzXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdDM0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhmaWVsZFNpbnQ2NExpc3QzNF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0RmllbGRTaW50NjRMaXN0MzRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcoZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0ME1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfWZpZWxkRW51bUxpc3RQYWNrZWQ0NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcoZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0xpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N01lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTMpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgKICAgICAgICAgICAgICA1MywgKGRvdWJsZSkoKGphdmEubGFuZy5Eb3VibGUpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKAogICAgICAgICAgICAgIDU0LCAoZmxvYXQpKChqYXZhLmxhbmcuRmxvYXQpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKAogICAgICAgICAgICAgIDU1LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemUoCiAgICAgICAgICAgICAgNTYsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTcpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKAogICAgICAgICAgICAgIDU3LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoCiAgICAgICAgICAgICAgNTgsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQzMlNpemUoCiAgICAgICAgICAgICAgNTksIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgKICAgICAgICAgICAgICA2MCwgKGJvb2xlYW4pKChqYXZhLmxhbmcuQm9vbGVhbikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNjEsIHRlc3RPbmVvZl8pOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MiwgKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgKICAgICAgICAgICAgICA2MywgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgdGVzdE9uZW9mXyk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoCiAgICAgICAgICAgICAgNjQsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoCiAgICAgICAgICAgICAgNjUsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXykpOwogICAgICB9CiAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQ2NFNpemUoCiAgICAgICAgICAgICAgNjYsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZSgKICAgICAgICAgICAgICA2NywgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfKSk7CiAgICAgIH0KICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY4KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoCiAgICAgICAgICAgICAgNjgsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl8pKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIG9iajsKCiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGREb3VibGUxKCkpCiAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgb3RoZXIuZ2V0RmllbGREb3VibGUxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmllbGRGbG9hdDIoKSkKICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZEZsb2F0MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRJbnQ2NDMoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRJbnQ2NDMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRVaW50NjQ0KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDY0NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZEludDMyNSgpCiAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEludDMyNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkNjQ2KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkRml4ZWQ2NDYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyNygpCiAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldEZpZWxkQm9vbDgoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRCb29sOCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTdHJpbmc5KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTdHJpbmc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZE1lc3NhZ2UxMCgpICE9IG90aGVyLmhhc0ZpZWxkTWVzc2FnZTEwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkTWVzc2FnZTEwKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTEwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2UxMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0RmllbGRCeXRlczExKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlczExKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMjEyKCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDMyMTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZmllbGRFbnVtMTNfICE9IG90aGVyLmZpZWxkRW51bTEzXykgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMjE0KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkMzIxNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0MTUoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDE1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldEZpZWxkU2ludDMyMTYoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTaW50MzIxNigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRGaWVsZFNpbnQ2NDE3KCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDY0MTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRG91YmxlTGlzdDE4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGbG9hdExpc3QxOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEludDY0TGlzdDIwTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRVaW50NjRMaXN0MjFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQzMkxpc3QyMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQ2NExpc3QyM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRGaXhlZDMyTGlzdDI0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEJvb2xMaXN0MjVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nTGlzdDI2TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1lc3NhZ2VMaXN0MjdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRCeXRlc0xpc3QyOExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDMyTGlzdDI5TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWZpZWxkRW51bUxpc3QzMF8uZXF1YWxzKG90aGVyLmZpZWxkRW51bUxpc3QzMF8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNmaXhlZDMyTGlzdDMxTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQzMkxpc3QzM0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkSW50MzJMaXN0UGFja2VkMzlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFmaWVsZEVudW1MaXN0UGFja2VkNDRfLmVxdWFscyhvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VGVzdE9uZW9mQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRUZXN0T25lb2ZDYXNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHN3aXRjaCAodGVzdE9uZW9mQ2FzZV8pIHsKICAgICAgICBjYXNlIDUzOgogICAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTUzKCkpCiAgICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgICBvdGhlci5nZXRGaWVsZERvdWJsZTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU0OgogICAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRGaWVsZEZsb2F0NTQoKSkKICAgICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICAgIG90aGVyLmdldEZpZWxkRmxvYXQ1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NToKICAgICAgICAgIGlmIChnZXRGaWVsZEludDY0NTUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50NjQ1NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU2OgogICAgICAgICAgaWYgKGdldEZpZWxkVWludDY0NTYoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDY0NTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NzoKICAgICAgICAgIGlmIChnZXRGaWVsZEludDMyNTcoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkSW50MzI1NygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NDU4KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkNjQ1OCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgaWYgKGdldEZpZWxkRml4ZWQzMjU5KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEZpeGVkMzI1OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYwOgogICAgICAgICAgaWYgKGdldEZpZWxkQm9vbDYwKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZEJvb2w2MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgaWYgKCFnZXRGaWVsZFN0cmluZzYxKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nNjEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjI6CiAgICAgICAgICBpZiAoIWdldEZpZWxkTWVzc2FnZTYyKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkTWVzc2FnZTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYzOgogICAgICAgICAgaWYgKCFnZXRGaWVsZEJ5dGVzNjMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlczYzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY0OgogICAgICAgICAgaWYgKGdldEZpZWxkVWludDMyNjQoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkVWludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2NToKICAgICAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDMyNjUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ZpeGVkMzI2NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY2OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ZpeGVkNjQ2NigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDY2KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICBpZiAoZ2V0RmllbGRTaW50MzI2NygpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGRTaW50MzI2NygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgaWYgKGdldEZpZWxkU2ludDY0NjgoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkU2ludDY0NjgoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9ET1VCTEVfMV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RmllbGREb3VibGUxKCkpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRkxPQVRfMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgIGdldEZpZWxkRmxvYXQyKCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQ2NF8zX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldEZpZWxkSW50NjQzKCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UNjRfNF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NDQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyXzVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyNSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDY0XzZfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0RmllbGRGaXhlZDY0NigpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQzMl83X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyNygpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MXzhfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgZ2V0RmllbGRCb29sOCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HXzlfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFN0cmluZzkoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CWVRFU18xMV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXMxMSgpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQzMl8xMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyMTIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRU5VTV8xM19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkRW51bTEzXzsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfMTRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyMTQoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVENjRfMTVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NDE1KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfMTZfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQzMjE2KCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF8xN19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRGaWVsZFNpbnQ2NDE3KCkpOwogICAgICBpZiAoZ2V0RmllbGREb3VibGVMaXN0MThDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0RPVUJMRV9MSVNUXzE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZERvdWJsZUxpc3QxOExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZsb2F0TGlzdDE5Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF9MSVNUXzE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZsb2F0TGlzdDE5TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkSW50NjRMaXN0MjBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0X0xJU1RfMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50NjRMaXN0MjBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRVaW50NjRMaXN0MjFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF9MSVNUXzIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDMyTGlzdDIyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl9MSVNUXzIyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQ2NF9MSVNUXzIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRGaXhlZDMyTGlzdDI0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GSVhFRDMyX0xJU1RfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQzMkxpc3QyNExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEJvb2xMaXN0MjVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfTElTVF8yNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU3RyaW5nTGlzdDI2Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TVFJJTkdfTElTVF8yNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRNZXNzYWdlTGlzdDI3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NRVNTQUdFX0xJU1RfMjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEJ5dGVzTGlzdDI4Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CWVRFU19MSVNUXzI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEJ5dGVzTGlzdDI4TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkVWludDMyTGlzdDI5Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9VSU5UMzJfTElTVF8yOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRFbnVtTGlzdDMwQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9FTlVNX0xJU1RfMzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkRW51bUxpc3QzMF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfTElTVF8zMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFNmaXhlZDY0TGlzdDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF9MSVNUXzMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDY0TGlzdDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZpZWxkU2ludDMyTGlzdDMzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfTElTVF8zM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzJMaXN0MzNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF9MSVNUXzM0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNpbnQ2NExpc3QzNExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRE9VQkxFX0xJU1RfUEFDS0VEXzM1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF9MSVNUX1BBQ0tFRF8zNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGbG9hdExpc3RQYWNrZWQzNkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQ2NF9MSVNUX1BBQ0tFRF8zN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDY0X0xJU1RfUEFDS0VEXzM4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9JTlQzMl9MSVNUX1BBQ0tFRF8zOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVENjRfTElTVF9QQUNLRURfNDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfTElTVF9QQUNLRURfNDFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEJvb2xMaXN0UGFja2VkNDJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfTElTVF9QQUNLRURfNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyX0xJU1RfUEFDS0VEXzQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0VOVU1fTElTVF9QQUNLRURfNDRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVEMzJfTElTVF9QQUNLRURfNDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU0ZJWEVENjRfTElTVF9QQUNLRURfNDZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQzMl9MSVNUX1BBQ0tFRF80N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF9MSVNUX1BBQ0tFRF80OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKHRlc3RPbmVvZkNhc2VfKSB7CiAgICAgICAgY2FzZSA1MzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0RPVUJMRV81M19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRGaWVsZERvdWJsZTUzKCkpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9GTE9BVF81NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgZ2V0RmllbGRGbG9hdDU0KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDY0XzU1X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgICAgZ2V0RmllbGRJbnQ2NDU1KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1NjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQ2NF81Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkVWludDY0NTYoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU3OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UMzJfNTdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRJbnQzMjU3KCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklYRUQ2NF81OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkRml4ZWQ2NDU4KCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1OToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZJWEVEMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRGaXhlZDMyNTkoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjA6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9CT09MXzYwX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgICAgZ2V0RmllbGRCb29sNjAoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfU1RSSU5HXzYxX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU3RyaW5nNjEoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01FU1NBR0VfNjJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRNZXNzYWdlNjIoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2MzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JZVEVTXzYzX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXM2MygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDMyXzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkVWludDMyNjQoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjU6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQzMl82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFNmaXhlZDMyNjUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjY6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TRklYRUQ2NF82Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkU2ZpeGVkNjQ2NigpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRTaW50MzI2NygpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2ODoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1NJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEZpZWxkU2ludDY0NjgoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2UxMEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBiaXRGaWVsZDFfID0gMDsKICAgICAgICBmaWVsZERvdWJsZTFfID0gMEQ7CiAgICAgICAgZmllbGRGbG9hdDJfID0gMEY7CiAgICAgICAgZmllbGRJbnQ2NDNfID0gMEw7CiAgICAgICAgZmllbGRVaW50NjQ0XyA9IDBMOwogICAgICAgIGZpZWxkSW50MzI1XyA9IDA7CiAgICAgICAgZmllbGRGaXhlZDY0Nl8gPSAwTDsKICAgICAgICBmaWVsZEZpeGVkMzI3XyA9IDA7CiAgICAgICAgZmllbGRCb29sOF8gPSBmYWxzZTsKICAgICAgICBmaWVsZFN0cmluZzlfID0gIiI7CiAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmaWVsZEJ5dGVzMTFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAgIGZpZWxkVWludDMyMTJfID0gMDsKICAgICAgICBmaWVsZEVudW0xM18gPSAwOwogICAgICAgIGZpZWxkU2ZpeGVkMzIxNF8gPSAwOwogICAgICAgIGZpZWxkU2ZpeGVkNjQxNV8gPSAwTDsKICAgICAgICBmaWVsZFNpbnQzMjE2XyA9IDA7CiAgICAgICAgZmllbGRTaW50NjQxN18gPSAwTDsKICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0MjJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBudWxsOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRFbnVtTGlzdDMwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHJlc3VsdCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuZmllbGRNZXNzYWdlTGlzdDI3XyA9IGZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1lc3NhZ2VMaXN0MjdfID0gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRFbnVtTGlzdDMwXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5maWVsZEVudW1MaXN0MzBfID0gZmllbGRFbnVtTGlzdDMwXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBmaWVsZEVudW1MaXN0UGFja2VkNDRfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZERvdWJsZTFfID0gZmllbGREb3VibGUxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEZsb2F0Ml8gPSBmaWVsZEZsb2F0Ml87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQ2NDNfID0gZmllbGRJbnQ2NDNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDY0NF8gPSBmaWVsZFVpbnQ2NDRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzI1XyA9IGZpZWxkSW50MzI1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkNjQ2XyA9IGZpZWxkRml4ZWQ2NDZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQzMjdfID0gZmllbGRGaXhlZDMyN187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRCb29sOF8gPSBmaWVsZEJvb2w4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFN0cmluZzlfID0gZmllbGRTdHJpbmc5XzsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNZXNzYWdlMTBfID0gZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmaWVsZE1lc3NhZ2UxMF8KICAgICAgICAgICAgICA6IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZEJ5dGVzMTFfID0gZmllbGRCeXRlczExXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQzMjEyXyA9IGZpZWxkVWludDMyMTJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRW51bTEzXyA9IGZpZWxkRW51bTEzXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDMyMTRfID0gZmllbGRTZml4ZWQzMjE0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNmaXhlZDY0MTVfID0gZmllbGRTZml4ZWQ2NDE1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQzMjE2XyA9IGZpZWxkU2ludDMyMTZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDY0MTdfID0gZmllbGRTaW50NjQxN187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRG91YmxlTGlzdDE4XyA9IGZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZsb2F0TGlzdDE5XyA9IGZpZWxkRmxvYXRMaXN0MTlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkSW50NjRMaXN0MjBfID0gZmllbGRJbnQ2NExpc3QyMF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkVWludDY0TGlzdDIxXyA9IGZpZWxkVWludDY0TGlzdDIxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDMyTGlzdDIyXyA9IGZpZWxkSW50MzJMaXN0MjJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDY0TGlzdDIzXyA9IGZpZWxkRml4ZWQ2NExpc3QyM187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEZpeGVkMzJMaXN0MjRfID0gZmllbGRGaXhlZDMyTGlzdDI0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkQm9vbExpc3QyNV8gPSBmaWVsZEJvb2xMaXN0MjVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFN0cmluZ0xpc3QyNl8gPSBmaWVsZFN0cmluZ0xpc3QyNl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRCeXRlc0xpc3QyOF8gPSBmaWVsZEJ5dGVzTGlzdDI4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50MzJMaXN0MjlfID0gZmllbGRVaW50MzJMaXN0MjlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQ2NExpc3QzMl8gPSBmaWVsZFNmaXhlZDY0TGlzdDMyXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMV8gPSBiaXRGaWVsZDFfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ludDMyTGlzdDMzXyA9IGZpZWxkU2ludDMyTGlzdDMzXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50NjRMaXN0MzRfID0gZmllbGRTaW50NjRMaXN0MzRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGZpZWxkSW50NjRMaXN0UGFja2VkMzdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBmaWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZEJvb2xMaXN0UGFja2VkNDJfID0gZmllbGRCb29sTGlzdFBhY2tlZDQyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfID0gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZmllbGRTaW50MzJMaXN0UGFja2VkNDdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF87CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSByZXN1bHQpIHsKICAgICAgICByZXN1bHQudGVzdE9uZW9mQ2FzZV8gPSB0ZXN0T25lb2ZDYXNlXzsKICAgICAgICByZXN1bHQudGVzdE9uZW9mXyA9IHRoaXMudGVzdE9uZW9mXzsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIgJiYKICAgICAgICAgICAgZmllbGRNZXNzYWdlNjJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQudGVzdE9uZW9mXyA9IGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGREb3VibGUxKCkgIT0gMEQpIHsKICAgICAgICAgIHNldEZpZWxkRG91YmxlMShvdGhlci5nZXRGaWVsZERvdWJsZTEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRGaWVsZEZsb2F0MigpICE9IDBGKSB7CiAgICAgICAgICBzZXRGaWVsZEZsb2F0MihvdGhlci5nZXRGaWVsZEZsb2F0MigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkSW50NjQzKCkgIT0gMEwpIHsKICAgICAgICAgIHNldEZpZWxkSW50NjQzKG90aGVyLmdldEZpZWxkSW50NjQzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRVaW50NjQ0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldEZpZWxkVWludDY0NChvdGhlci5nZXRGaWVsZFVpbnQ2NDQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRGaWVsZEludDMyNSgpICE9IDApIHsKICAgICAgICAgIHNldEZpZWxkSW50MzI1KG90aGVyLmdldEZpZWxkSW50MzI1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRGaXhlZDY0NigpICE9IDBMKSB7CiAgICAgICAgICBzZXRGaWVsZEZpeGVkNjQ2KG90aGVyLmdldEZpZWxkRml4ZWQ2NDYoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkgIT0gMCkgewogICAgICAgICAgc2V0RmllbGRGaXhlZDMyNyhvdGhlci5nZXRGaWVsZEZpeGVkMzI3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRCb29sOCgpICE9IGZhbHNlKSB7CiAgICAgICAgICBzZXRGaWVsZEJvb2w4KG90aGVyLmdldEZpZWxkQm9vbDgoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0RmllbGRTdHJpbmc5KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBmaWVsZFN0cmluZzlfID0gb3RoZXIuZmllbGRTdHJpbmc5XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRNZXNzYWdlMTAoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZE1lc3NhZ2UxMChvdGhlci5nZXRGaWVsZE1lc3NhZ2UxMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkQnl0ZXMxMSgpICE9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSkgewogICAgICAgICAgc2V0RmllbGRCeXRlczExKG90aGVyLmdldEZpZWxkQnl0ZXMxMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkVWludDMyMTIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRGaWVsZFVpbnQzMjEyKG90aGVyLmdldEZpZWxkVWludDMyMTIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5maWVsZEVudW0xM18gIT0gMCkgewogICAgICAgICAgc2V0RmllbGRFbnVtMTNWYWx1ZShvdGhlci5nZXRGaWVsZEVudW0xM1ZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRTZml4ZWQzMjE0KCkgIT0gMCkgewogICAgICAgICAgc2V0RmllbGRTZml4ZWQzMjE0KG90aGVyLmdldEZpZWxkU2ZpeGVkMzIxNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkU2ZpeGVkNjQxNSgpICE9IDBMKSB7CiAgICAgICAgICBzZXRGaWVsZFNmaXhlZDY0MTUob3RoZXIuZ2V0RmllbGRTZml4ZWQ2NDE1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0RmllbGRTaW50MzIxNigpICE9IDApIHsKICAgICAgICAgIHNldEZpZWxkU2ludDMyMTYob3RoZXIuZ2V0RmllbGRTaW50MzIxNigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkU2ludDY0MTcoKSAhPSAwTCkgewogICAgICAgICAgc2V0RmllbGRTaW50NjQxNyhvdGhlci5nZXRGaWVsZFNpbnQ2NDE3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRG91YmxlTGlzdDE4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZERvdWJsZUxpc3QxOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IG90aGVyLmZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0MThfLmFkZEFsbChvdGhlci5maWVsZERvdWJsZUxpc3QxOF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGbG9hdExpc3QxOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGbG9hdExpc3QxOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gb3RoZXIuZmllbGRGbG9hdExpc3QxOV87CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRBbGwob3RoZXIuZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQ2NExpc3QyMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQ2NExpc3QyMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gb3RoZXIuZmllbGRJbnQ2NExpc3QyMF87CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5hZGRBbGwob3RoZXIuZmllbGRJbnQ2NExpc3QyMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50NjRMaXN0MjFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDY0TGlzdDIxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfID0gb3RoZXIuZmllbGRVaW50NjRMaXN0MjFfOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8uYWRkQWxsKG90aGVyLmZpZWxkVWludDY0TGlzdDIxXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEludDMyTGlzdDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEludDMyTGlzdDIyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBvdGhlci5maWVsZEludDMyTGlzdDIyXzsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEFsbChvdGhlci5maWVsZEludDMyTGlzdDIyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRml4ZWQ2NExpc3QyM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18gPSBvdGhlci5maWVsZEZpeGVkNjRMaXN0MjNfOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkQWxsKG90aGVyLmZpZWxkRml4ZWQ2NExpc3QyM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkMzJMaXN0MjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gb3RoZXIuZmllbGRGaXhlZDMyTGlzdDI0XzsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQm9vbExpc3QyNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRCb29sTGlzdDI1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG90aGVyLmZpZWxkQm9vbExpc3QyNV87CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCb29sTGlzdDI1Xy5hZGRBbGwob3RoZXIuZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFN0cmluZ0xpc3QyNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTdHJpbmdMaXN0MjZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFN0cmluZ0xpc3QyNl8gPSBvdGhlci5maWVsZFN0cmluZ0xpc3QyNl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU3RyaW5nTGlzdDI2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGRBbGwob3RoZXIuZmllbGRTdHJpbmdMaXN0MjZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3XzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGRBbGwob3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIuZmllbGRNZXNzYWdlTGlzdDI3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3XyA9IG90aGVyLmZpZWxkTWVzc2FnZUxpc3QyN187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5maWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkQnl0ZXNMaXN0MjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IG90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfOwogICAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkQnl0ZXNMaXN0MjhJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uYWRkQWxsKG90aGVyLmZpZWxkQnl0ZXNMaXN0MjhfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkVWludDMyTGlzdDI5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFVpbnQzMkxpc3QyOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5XyA9IG90aGVyLmZpZWxkVWludDMyTGlzdDI5XzsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0MjlJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEFsbChvdGhlci5maWVsZFVpbnQzMkxpc3QyOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRFbnVtTGlzdDMwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEVudW1MaXN0MzBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gb3RoZXIuZmllbGRFbnVtTGlzdDMwXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkQWxsKG90aGVyLmZpZWxkRW51bUxpc3QzMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTZml4ZWQzMkxpc3QzMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfID0gb3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5hZGRBbGwob3RoZXIuZmllbGRTZml4ZWQzMkxpc3QzMV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTZml4ZWQ2NExpc3QzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gb3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRBbGwob3RoZXIuZmllbGRTZml4ZWQ2NExpc3QzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50MzJMaXN0MzNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDMyTGlzdDMzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gb3RoZXIuZmllbGRTaW50MzJMaXN0MzNfOwogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uYWRkQWxsKG90aGVyLmZpZWxkU2ludDMyTGlzdDMzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFNpbnQ2NExpc3QzNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRTaW50NjRMaXN0MzRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8gPSBvdGhlci5maWVsZFNpbnQ2NExpc3QzNF87CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0Xy5hZGRBbGwob3RoZXIuZmllbGRTaW50NjRMaXN0MzRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IG90aGVyLmZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XzsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZEFsbChvdGhlci5maWVsZERvdWJsZUxpc3RQYWNrZWQzNV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gb3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl87CiAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRBbGwob3RoZXIuZmllbGRGbG9hdExpc3RQYWNrZWQzNl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfID0gb3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRBbGwob3RoZXIuZmllbGRJbnQ2NExpc3RQYWNrZWQzN18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gb3RoZXIuZmllbGRVaW50NjRMaXN0UGFja2VkMzhfOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkQWxsKG90aGVyLmZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8gPSBvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmFkZEFsbChvdGhlci5maWVsZEludDMyTGlzdFBhY2tlZDM5Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBvdGhlci5maWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfOwogICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uYWRkQWxsKG90aGVyLmZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfID0gb3RoZXIuZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLmFkZEFsbChvdGhlci5maWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRCb29sTGlzdFBhY2tlZDQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXyA9IG90aGVyLmZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRBbGwob3RoZXIuZmllbGRCb29sTGlzdFBhY2tlZDQyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBvdGhlci5maWVsZFVpbnQzMkxpc3RQYWNrZWQ0M187CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRBbGwob3RoZXIuZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9IG90aGVyLmZpZWxkRW51bUxpc3RQYWNrZWQ0NF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmFkZEFsbChvdGhlci5maWVsZEVudW1MaXN0UGFja2VkNDRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XyA9IG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XyA9IG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfOwogICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uYWRkQWxsKG90aGVyLmZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XyA9IG90aGVyLmZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0UGFja2VkNDdJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEFsbChvdGhlci5maWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gb3RoZXIuZmllbGRTaW50NjRMaXN0UGFja2VkNDhfOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkQWxsKG90aGVyLmZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRUZXN0T25lb2ZDYXNlKCkpIHsKICAgICAgICAgIGNhc2UgRklFTERfRE9VQkxFXzUzOiB7CiAgICAgICAgICAgIHNldEZpZWxkRG91YmxlNTMob3RoZXIuZ2V0RmllbGREb3VibGU1MygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0ZMT0FUXzU0OiB7CiAgICAgICAgICAgIHNldEZpZWxkRmxvYXQ1NChvdGhlci5nZXRGaWVsZEZsb2F0NTQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9JTlQ2NF81NTogewogICAgICAgICAgICBzZXRGaWVsZEludDY0NTUob3RoZXIuZ2V0RmllbGRJbnQ2NDU1KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfVUlOVDY0XzU2OiB7CiAgICAgICAgICAgIHNldEZpZWxkVWludDY0NTYob3RoZXIuZ2V0RmllbGRVaW50NjQ1NigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0lOVDMyXzU3OiB7CiAgICAgICAgICAgIHNldEZpZWxkSW50MzI1NyhvdGhlci5nZXRGaWVsZEludDMyNTcoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9GSVhFRDY0XzU4OiB7CiAgICAgICAgICAgIHNldEZpZWxkRml4ZWQ2NDU4KG90aGVyLmdldEZpZWxkRml4ZWQ2NDU4KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfRklYRUQzMl81OTogewogICAgICAgICAgICBzZXRGaWVsZEZpeGVkMzI1OShvdGhlci5nZXRGaWVsZEZpeGVkMzI1OSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX0JPT0xfNjA6IHsKICAgICAgICAgICAgc2V0RmllbGRCb29sNjAob3RoZXIuZ2V0RmllbGRCb29sNjAoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TVFJJTkdfNjE6IHsKICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG90aGVyLnRlc3RPbmVvZl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfTUVTU0FHRV82MjogewogICAgICAgICAgICBtZXJnZUZpZWxkTWVzc2FnZTYyKG90aGVyLmdldEZpZWxkTWVzc2FnZTYyKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfQllURVNfNjM6IHsKICAgICAgICAgICAgc2V0RmllbGRCeXRlczYzKG90aGVyLmdldEZpZWxkQnl0ZXM2MygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1VJTlQzMl82NDogewogICAgICAgICAgICBzZXRGaWVsZFVpbnQzMjY0KG90aGVyLmdldEZpZWxkVWludDMyNjQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TRklYRUQzMl82NTogewogICAgICAgICAgICBzZXRGaWVsZFNmaXhlZDMyNjUob3RoZXIuZ2V0RmllbGRTZml4ZWQzMjY1KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRklFTERfU0ZJWEVENjRfNjY6IHsKICAgICAgICAgICAgc2V0RmllbGRTZml4ZWQ2NDY2KG90aGVyLmdldEZpZWxkU2ZpeGVkNjQ2NigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZJRUxEX1NJTlQzMl82NzogewogICAgICAgICAgICBzZXRGaWVsZFNpbnQzMjY3KG90aGVyLmdldEZpZWxkU2ludDMyNjcoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGSUVMRF9TSU5UNjRfNjg6IHsKICAgICAgICAgICAgc2V0RmllbGRTaW50NjQ2OChvdGhlci5nZXRGaWVsZFNpbnQ2NDY4KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgVEVTVE9ORU9GX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgOTogewogICAgICAgICAgICAgICAgZmllbGREb3VibGUxXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5CiAgICAgICAgICAgICAgY2FzZSAyMTogewogICAgICAgICAgICAgICAgZmllbGRGbG9hdDJfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDY0M18gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGZpZWxkVWludDY0NF8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBmaWVsZEludDMyNV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDk6IHsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NDZfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OQogICAgICAgICAgICAgIGNhc2UgNjE6IHsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQzMjdfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbDhfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NAogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkU3RyaW5nOV8gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkVWludDMyMTJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkRW51bTEzXyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMTc6IHsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzIxNF8gPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTcKICAgICAgICAgICAgICBjYXNlIDEyMTogewogICAgICAgICAgICAgICAgZmllbGRTZml4ZWQ2NDE1XyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMQogICAgICAgICAgICAgIGNhc2UgMTI4OiB7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMjE2XyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjgKICAgICAgICAgICAgICBjYXNlIDEzNjogewogICAgICAgICAgICAgICAgZmllbGRTaW50NjQxN18gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2CiAgICAgICAgICAgICAgY2FzZSAxNDU6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ1CiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTc6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NwogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGbG9hdExpc3QxOUlzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjA6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAKICAgICAgICAgICAgICBjYXNlIDE2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTY4OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzAKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODU6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODUKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3QyNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk3CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDA6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDAKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTdHJpbmdMaXN0MjZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQocyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxOAogICAgICAgICAgICAgIGNhc2UgMjI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uYWRkKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIyNgogICAgICAgICAgICAgIGNhc2UgMjMyOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIzMgogICAgICAgICAgICAgIGNhc2UgMjM0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5hZGRJbnQoaW5wdXQucmVhZFVJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMzQKICAgICAgICAgICAgICBjYXNlIDI0MDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQwCiAgICAgICAgICAgICAgY2FzZSAyNDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgZmllbGRFbnVtTGlzdDMwXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNDIKICAgICAgICAgICAgICBjYXNlIDI1MzogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0MzFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTMKICAgICAgICAgICAgICBjYXNlIDI1MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0MzFJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3QzMV8uYWRkSW50KGlucHV0LnJlYWRTRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1NzogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1NwogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5hZGRMb25nKGlucHV0LnJlYWRTRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBjYXNlIDI2NDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNjQKICAgICAgICAgICAgICBjYXNlIDI2NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY2CiAgICAgICAgICAgICAgY2FzZSAyNzI6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzIKICAgICAgICAgICAgICBjYXNlIDI3NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3NAogICAgICAgICAgICAgIGNhc2UgMjgxOiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MQogICAgICAgICAgICAgIGNhc2UgMjgyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MgogICAgICAgICAgICAgIGNhc2UgMjkzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTMKICAgICAgICAgICAgICBjYXNlIDI5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0UGFja2VkMzZJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMjk2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjk2CiAgICAgICAgICAgICAgY2FzZSAyOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyOTgKICAgICAgICAgICAgICBjYXNlIDMwNDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNAogICAgICAgICAgICAgIGNhc2UgMzA2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5hZGRMb25nKGlucHV0LnJlYWRVSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA2CiAgICAgICAgICAgICAgY2FzZSAzMTI6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzEyCiAgICAgICAgICAgICAgY2FzZSAzMTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5Xy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNAogICAgICAgICAgICAgIGNhc2UgMzIxOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIxCiAgICAgICAgICAgICAgY2FzZSAzMjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMgogICAgICAgICAgICAgIGNhc2UgMzMzOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMwogICAgICAgICAgICAgIGNhc2UgMzMwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMAogICAgICAgICAgICAgIGNhc2UgMzM2OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM2CiAgICAgICAgICAgICAgY2FzZSAzMzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ0OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NAogICAgICAgICAgICAgIGNhc2UgMzQ2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5hZGRJbnQoaW5wdXQucmVhZFVJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNDYKICAgICAgICAgICAgICBjYXNlIDM1MjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzUyCiAgICAgICAgICAgICAgY2FzZSAzNTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTQKICAgICAgICAgICAgICBjYXNlIDM2NTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjUKICAgICAgICAgICAgICBjYXNlIDM2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KGlucHV0LnJlYWRTRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjIKICAgICAgICAgICAgICBjYXNlIDM2OTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2OQogICAgICAgICAgICAgIGNhc2UgMzcwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKGlucHV0LnJlYWRTRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzAKICAgICAgICAgICAgICBjYXNlIDM3NjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzYKICAgICAgICAgICAgICBjYXNlIDM3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzc4CiAgICAgICAgICAgICAgY2FzZSAzODQ6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzODQKICAgICAgICAgICAgICBjYXNlIDM4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM4NgogICAgICAgICAgICAgIGNhc2UgNDI1OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1MzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MjUKICAgICAgICAgICAgICBjYXNlIDQzNzogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MzcKICAgICAgICAgICAgICBjYXNlIDQ0MDogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NDAKICAgICAgICAgICAgICBjYXNlIDQ0ODogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTY7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDQ4CiAgICAgICAgICAgICAgY2FzZSA0NTY6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDU2CiAgICAgICAgICAgICAgY2FzZSA0NjU6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1ODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NjUKICAgICAgICAgICAgICBjYXNlIDQ3NzogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU5OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ3NwogICAgICAgICAgICAgIGNhc2UgNDgwOiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgwCiAgICAgICAgICAgICAgY2FzZSA0OTA6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ5MAogICAgICAgICAgICAgIGNhc2UgNDk4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2U2MkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ5OAogICAgICAgICAgICAgIGNhc2UgNTA2OiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNgogICAgICAgICAgICAgIGNhc2UgNTEyOiB7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBjYXNlIDUyNTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjUKICAgICAgICAgICAgICBjYXNlIDUyOTogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjkKICAgICAgICAgICAgICBjYXNlIDUzNjogewogICAgICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTM2CiAgICAgICAgICAgICAgY2FzZSA1NDQ6IHsKICAgICAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU0NAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHRlc3RPbmVvZl87CiAgICAgIHB1YmxpYyBUZXN0T25lb2ZDYXNlCiAgICAgICAgICBnZXRUZXN0T25lb2ZDYXNlKCkgewogICAgICAgIHJldHVybiBUZXN0T25lb2ZDYXNlLmZvck51bWJlcigKICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8pOwogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclRlc3RPbmVvZigpIHsKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMV87CgogICAgICBwcml2YXRlIGRvdWJsZSBmaWVsZERvdWJsZTFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGUxKCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZTFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZERvdWJsZTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZERvdWJsZTEoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGZpZWxkRG91YmxlMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZmllbGREb3VibGUxXyA9IDBEOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IGZpZWxkRmxvYXQyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRGbG9hdDIoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdDIoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRGbG9hdDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdDIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGZpZWxkRmxvYXQyXyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRJbnQ2NDNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NDMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjQzKCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0M187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzMgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjQzKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZmllbGRJbnQ2NDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF8zID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQ2NDMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGZpZWxkSW50NjQzXyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRVaW50NjQ0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQ0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFVpbnQ2NDQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0NChsb25nIHZhbHVlKSB7CgogICAgICAgIGZpZWxkVWludDY0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBmaWVsZF91aW50NjRfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgZmllbGRVaW50NjQ0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZEludDMyNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyNS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNSgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMjVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyNShpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRJbnQzMjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMjUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGZpZWxkSW50MzI1XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBmaWVsZEZpeGVkNjQ2XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjQ2LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjQ2KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjQ2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBmaWVsZF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDY0Nihsb25nIHZhbHVlKSB7CgogICAgICAgIGZpZWxkRml4ZWQ2NDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQ2NDYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGZpZWxkRml4ZWQ2NDZfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkRml4ZWQzMjdfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMjcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyNygpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgZmllbGRfZml4ZWQzMl83ID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQzMjcoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGZpZWxkRml4ZWQzMjdfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGZpZWxkQm9vbDhfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbDguCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbDgoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbDhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIGZpZWxkX2Jvb2xfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJvb2w4KGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZmllbGRCb29sOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF84ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCb29sOCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgZmllbGRCb29sOF8gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkU3RyaW5nOV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFN0cmluZzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZFN0cmluZzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZFN0cmluZzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgZmllbGRTdHJpbmc5XyA9IHM7CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkU3RyaW5nOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZpZWxkU3RyaW5nOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZmllbGRTdHJpbmc5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgZmllbGRTdHJpbmc5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU3RyaW5nOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZpZWxkU3RyaW5nOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU3RyaW5nOSgpIHsKICAgICAgICBmaWVsZFN0cmluZzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RmllbGRTdHJpbmc5KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgZmllbGRTdHJpbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRNZXNzYWdlMTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGZpZWxkTWVzc2FnZTEwQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlMTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNZXNzYWdlMTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTWVzc2FnZTEwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZE1lc3NhZ2UxMF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWVzc2FnZTEwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNZXNzYWdlMTAoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkTWVzc2FnZTEwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gIT0gbnVsbCAmJgogICAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1lc3NhZ2UxMCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgZmllbGRNZXNzYWdlMTBfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlMTBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIGdldEZpZWxkTWVzc2FnZTEwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZTEwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZTEwT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2UxMEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTEwXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZE1lc3NhZ2UxMF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRNZXNzYWdlMTBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTEwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNZXNzYWdlMTBCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWVzc2FnZTEwKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2UxMF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlMTBCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZmllbGRCeXRlczExXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJ5dGVzMTEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczExKCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzMTFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzMTEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZEJ5dGVzMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJ5dGVzMTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGZpZWxkQnl0ZXMxMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZEJ5dGVzMTEoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRVaW50MzIxMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzIxMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMjEyKCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMjEyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl8xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQzMjEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzIxMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRVaW50MzIxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRVaW50MzIxMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgZmllbGRVaW50MzIxMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZEVudW0xM18gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bTEzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldEZpZWxkRW51bTEzVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bTEzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEVudW0xM1ZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGZpZWxkRW51bTEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW0xMy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW0xMygpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLmZvck51bWJlcihmaWVsZEVudW0xM18pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV8xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEVudW0xMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bTEzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGZpZWxkRW51bTEzXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRFbnVtMTMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGZpZWxkRW51bTEzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkU2ZpeGVkMzIxNF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzIxNC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyMTQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzIxNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzIxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkMzIxNChpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRTZml4ZWQzMjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQzMjE0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBmaWVsZFNmaXhlZDMyMTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGZpZWxkU2ZpeGVkNjQxNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjQxNS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NDE1KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0MTVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0MTUobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFNmaXhlZDY0MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF8xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0MTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGZpZWxkU2ZpeGVkNjQxNV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGRTaW50MzIxNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzIxNi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMjE2KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMjE2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMjE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzIxNihpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRTaW50MzIxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzIxNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgZmllbGRTaW50MzIxNl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZmllbGRTaW50NjQxN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTaW50NjQxNy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTaW50NjQxNygpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50NjQxN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjQxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ludDY0MTcobG9uZyB2YWx1ZSkgewoKICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IGZpZWxkX3NpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NDE3KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBmaWVsZFNpbnQ2NDE3XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBmaWVsZERvdWJsZUxpc3QxOF8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGREb3VibGVMaXN0MThfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUxpc3QxOF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGREb3VibGVMaXN0MThfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRG91YmxlTGlzdDE4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0MThfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRG91YmxlTGlzdDE4XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZERvdWJsZUxpc3QxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0RmllbGREb3VibGVMaXN0MThMaXN0KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0XzE4ID0gMTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRG91YmxlTGlzdDE4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZERvdWJsZUxpc3QxOENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3QxOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlTGlzdDE4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGREb3VibGVMaXN0MTgoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRG91YmxlTGlzdDE4Xy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdDE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGVMaXN0MTgoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3QxOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4Xy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRG91YmxlTGlzdDE4IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGREb3VibGVMaXN0MTgoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdDE4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGREb3VibGVMaXN0MThfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfMTggPSAxOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGREb3VibGVMaXN0MTggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZERvdWJsZUxpc3QxOCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0MThJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGREb3VibGVMaXN0MThfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF8xOCA9IDE4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlTGlzdDE4KCkgewogICAgICAgIGZpZWxkRG91YmxlTGlzdDE4XyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBmaWVsZEZsb2F0TGlzdDE5XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdDE5SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3QxOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0MTlfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZsb2F0TGlzdDE5SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGbG9hdExpc3QxOV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRmxvYXRMaXN0MTlfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZsb2F0TGlzdDE5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldEZpZWxkRmxvYXRMaXN0MTlMaXN0KCkgewogICAgICAgIGZpZWxkRmxvYXRMaXN0MTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3QxOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGbG9hdExpc3QxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGbG9hdExpc3QxOUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdDE5Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfMTkgPSAxOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXRMaXN0MTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXRMaXN0MTkoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0MTlfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGbG9hdExpc3QxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRmxvYXRMaXN0MTkoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXRMaXN0MTkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZsb2F0TGlzdDE5KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZsb2F0TGlzdDE5Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0XzE5ID0gMTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRmxvYXRMaXN0MTkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZsb2F0TGlzdDE5KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRmxvYXRMaXN0MTlJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGbG9hdExpc3QxOV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF8xOSA9IDE5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRmxvYXRMaXN0MTkoKSB7CiAgICAgICAgZmllbGRGbG9hdExpc3QxOV8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkSW50NjRMaXN0MjBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkSW50NjRMaXN0MjBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEludDY0TGlzdDIwXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEludDY0TGlzdDIwXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDY0TGlzdDIwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRJbnQ2NExpc3QyMExpc3QoKSB7CiAgICAgICAgZmllbGRJbnQ2NExpc3QyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdDIwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDY0TGlzdDIwLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDY0TGlzdDIwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRMaXN0MjBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NExpc3QyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEludDY0TGlzdDIwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdDIwXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgZmllbGRfaW50NjRfbGlzdF8yMCA9IDIwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NExpc3QyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjRMaXN0MjAoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3QyMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEludDY0TGlzdDIwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRJbnQ2NExpc3QyMChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0MjBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDY0TGlzdDIwXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRJbnQ2NExpc3QyMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkSW50NjRMaXN0MjAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdDIwSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkSW50NjRMaXN0MjBfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfMjAgPSAyMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDY0TGlzdDIwKCkgewogICAgICAgIGZpZWxkSW50NjRMaXN0MjBfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRVaW50NjRMaXN0MjFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NExpc3QyMV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRVaW50NjRMaXN0MjFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NExpc3QyMUxpc3QoKSB7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRVaW50NjRMaXN0MjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfMjEgPSAyMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50NjRMaXN0MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDY0TGlzdDIxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjRMaXN0MjEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjRMaXN0MjEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdDIxXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0XzIxID0gMjEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0TGlzdDIxKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdDIxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50NjRMaXN0MjFfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDY0TGlzdDIxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRVaW50NjRMaXN0MjEobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3QyMUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdDIxXy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZFVpbnQ2NExpc3QyMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkVWludDY0TGlzdDIxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0MjFJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRVaW50NjRMaXN0MjFfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF8yMSA9IDIxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0TGlzdDIxKCkgewogICAgICAgIGZpZWxkVWludDY0TGlzdDIxXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkSW50MzJMaXN0MjJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRJbnQzMkxpc3QyMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkSW50MzJMaXN0MjJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkSW50MzJMaXN0MjJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEludDMyTGlzdDIyTGlzdCgpIHsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0MjJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkSW50MzJMaXN0MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0MjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDMyTGlzdDIyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQzMkxpc3QyMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQzMkxpc3QyMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3QyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50MzJMaXN0MjIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdDIySXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmaWVsZF9pbnQzMl9saXN0XzIyID0gMjIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMkxpc3QyMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkSW50MzJMaXN0MjIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDMyTGlzdDIyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEludDMyTGlzdDIyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRJbnQzMkxpc3QyMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkSW50MzJMaXN0MjJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRJbnQzMkxpc3QyMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF8yMiA9IDIyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50MzJMaXN0MjIoKSB7CiAgICAgICAgZmllbGRJbnQzMkxpc3QyMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEZpeGVkNjRMaXN0MjNfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDY0TGlzdDIzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkNjRMaXN0MjNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkNjRMaXN0MjNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQ2NExpc3QyM18sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkNjRMaXN0MjNMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkNjRMaXN0MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQ2NExpc3QyM0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0MjNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfMjMgPSAyMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZEZpeGVkNjRMaXN0MjMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQ2NExpc3QyM18uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0XzIzID0gMjMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjRMaXN0MjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZpeGVkNjRMaXN0MjMoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdDIzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdDIzXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQ2NExpc3QyMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRml4ZWQ2NExpc3QyMyhsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3QyM0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3QyM18uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkNjRMaXN0MjMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkNjRMaXN0MjMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0MjNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDY0TGlzdDIzXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF8yMyA9IDIzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQ2NExpc3QyMygpIHsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0MjNfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRGaXhlZDMyTGlzdDI0XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDMyTGlzdDI0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRGaXhlZDMyTGlzdDI0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkMzJMaXN0MjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZEZpeGVkMzJMaXN0MjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRml4ZWQzMkxpc3QyNF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZEZpeGVkMzJMaXN0MjRMaXN0KCkgewogICAgICAgIGZpZWxkRml4ZWQzMkxpc3QyNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEZpeGVkMzJMaXN0MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkMzJMaXN0MjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfMjQgPSAyNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQzMkxpc3QyNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRml4ZWQzMkxpc3QyNChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdDI0Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyTGlzdDI0KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdDI0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdDI0Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0XzI0ID0gMjQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDMyTGlzdDI0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGaXhlZDMyTGlzdDI0KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZpeGVkMzJMaXN0MjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEZpeGVkMzJMaXN0MjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkMzJMaXN0MjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRGaXhlZDMyTGlzdDI0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF8yNCA9IDI0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRml4ZWQzMkxpc3QyNCgpIHsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0MjRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgZmllbGRCb29sTGlzdDI1XyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkQm9vbExpc3QyNV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3QyNV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCb29sTGlzdDI1Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRCb29sTGlzdDI1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJvb2xMaXN0MjVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRCb29sTGlzdDI1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0RmllbGRCb29sTGlzdDI1TGlzdCgpIHsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCb29sTGlzdDI1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEJvb2xMaXN0MjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdDI1Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0XzI1ID0gMjUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEJvb2xMaXN0MjUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRCb29sTGlzdDI1KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEJvb2xMaXN0MjVfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF8yNSA9IDI1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sTGlzdDI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sTGlzdDI1KAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3QyNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkQm9vbExpc3QyNV8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJvb2xMaXN0MjUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEJvb2xMaXN0MjUoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0MjVJc011dGFibGUoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0MjVfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRCb29sTGlzdDI1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRCb29sTGlzdDI1KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdDI1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkQm9vbExpc3QyNV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfMjUgPSAyNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2xMaXN0MjUoKSB7CiAgICAgICAgZmllbGRCb29sTGlzdDI1XyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU3RyaW5nTGlzdDI2Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTdHJpbmdMaXN0MjZfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChmaWVsZFN0cmluZ0xpc3QyNl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFN0cmluZ0xpc3QyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0RmllbGRTdHJpbmdMaXN0MjZMaXN0KCkgewogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU3RyaW5nTGlzdDI2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFN0cmluZ0xpc3QyNkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZmllbGRfc3RyaW5nX2xpc3RfMjYgPSAyNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkU3RyaW5nTGlzdDI2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFN0cmluZ0xpc3QyNl8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZpZWxkU3RyaW5nTGlzdDI2Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nTGlzdDI2Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFN0cmluZ0xpc3QyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU3RyaW5nTGlzdDI2KAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTdHJpbmdMaXN0MjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRTdHJpbmdMaXN0MjYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRTdHJpbmdMaXN0MjZJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRTdHJpbmdMaXN0MjZfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBmaWVsZF9zdHJpbmdfbGlzdF8yNiA9IDI2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU3RyaW5nTGlzdDI2KCkgewogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGZpZWxkX3N0cmluZ19saXN0XzI2ID0gMjYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIGZpZWxkU3RyaW5nTGlzdDI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTdHJpbmdMaXN0MjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVGaWVsZFN0cmluZ0xpc3QyNklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU3RyaW5nTGlzdDI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGZpZWxkTWVzc2FnZUxpc3QyN18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPihmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWVzc2FnZUxpc3QyN0xpc3QoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdDb3VudCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWVzc2FnZUxpc3QyNyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlRmllbGRNZXNzYWdlTGlzdDI3SXNNdXRhYmxlKCk7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjcoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWVzc2FnZUxpc3QyNygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRNZXNzYWdlTGlzdDI3KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVGaWVsZE1lc3NhZ2VMaXN0MjdJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIGZpZWxkTWVzc2FnZUxpc3QyN18pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1lc3NhZ2VMaXN0MjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1lc3NhZ2VMaXN0MjcoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUZpZWxkTWVzc2FnZUxpc3QyN0lzTXV0YWJsZSgpOwogICAgICAgICAgZmllbGRNZXNzYWdlTGlzdDI3Xy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldEZpZWxkTWVzc2FnZUxpc3QyN09yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3Xy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0RmllbGRNZXNzYWdlTGlzdDI3T3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZE1lc3NhZ2VMaXN0MjdfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV9saXN0XzI3ID0gMjcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgYWRkRmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSBmaWVsZF9tZXNzYWdlX2xpc3RfMjcgPSAyNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBhZGRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZUxpc3QyN0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfbGlzdF8yNyA9IDI3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNZXNzYWdlTGlzdDI3RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2VMaXN0MjdGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBmaWVsZE1lc3NhZ2VMaXN0MjdfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZpZWxkTWVzc2FnZUxpc3QyN18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNZXNzYWdlTGlzdDI3QnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkQnl0ZXNMaXN0MjhfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEJ5dGVzTGlzdDI4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZmllbGRfYnl0ZXNfbGlzdF8yOCA9IDI4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEJ5dGVzTGlzdDI4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldEZpZWxkQnl0ZXNMaXN0MjhMaXN0KCkgewogICAgICAgIGZpZWxkQnl0ZXNMaXN0MjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRCeXRlc0xpc3QyOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRCeXRlc0xpc3QyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCeXRlc0xpc3QyOENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXNMaXN0MjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZEJ5dGVzTGlzdDI4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEJ5dGVzTGlzdDI4Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEJ5dGVzTGlzdDI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCeXRlc0xpc3QyOCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZEJ5dGVzTGlzdDI4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCeXRlc0xpc3QyOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkQnl0ZXNMaXN0MjgoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVGaWVsZEJ5dGVzTGlzdDI4SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCeXRlc0xpc3QyOF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGZpZWxkX2J5dGVzX2xpc3RfMjggPSAyOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRCeXRlc0xpc3QyOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkQnl0ZXNMaXN0MjgoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRCeXRlc0xpc3QyOElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEJ5dGVzTGlzdDI4Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBmaWVsZF9ieXRlc19saXN0XzI4ID0gMjggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCeXRlc0xpc3QyOCgpIHsKICAgICAgICBmaWVsZEJ5dGVzTGlzdDI4XyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRVaW50MzJMaXN0MjlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkVWludDMyTGlzdDI5Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkVWludDMyTGlzdDI5Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDMyTGlzdDI5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRVaW50MzJMaXN0MjlMaXN0KCkgewogICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdDI5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0XzI5ID0gMjkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDMyTGlzdDI5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMkxpc3QyOUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkxpc3QyOV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyTGlzdDI5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzJMaXN0MjkoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdDI5Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDMyTGlzdDI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzJMaXN0MjkoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQzMkxpc3QyOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDMyTGlzdDI5Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF8yOSA9IDI5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDMyTGlzdDI5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRVaW50MzJMaXN0MjkoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50MzJMaXN0MjlfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRVaW50MzJMaXN0MjkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFVpbnQzMkxpc3QyOSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdDI5SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkVWludDMyTGlzdDI5Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfMjkgPSAyOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQzMkxpc3QyOSgpIHsKICAgICAgICBmaWVsZFVpbnQzMkxpc3QyOV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGZpZWxkRW51bUxpc3QzMF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KGZpZWxkRW51bUxpc3QzMF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRFbnVtTGlzdDMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gZ2V0RmllbGRFbnVtTGlzdDMwTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+KGZpZWxkRW51bUxpc3QzMF8sIGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRFbnVtTGlzdDMwLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0MzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0XzMwID0gMzAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZEVudW1MaXN0MzAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRW51bUxpc3QzMF9jb252ZXJ0ZXJfLmNvbnZlcnQoZmllbGRFbnVtTGlzdDMwXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3QzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bUxpc3QzMCgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0MzBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRW51bUxpc3QzMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3QzMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRFbnVtTGlzdDMwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdDMwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRW51bUxpc3QzMCgpIHsKICAgICAgICBmaWVsZEVudW1MaXN0MzBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdDMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZEVudW1MaXN0MzBWYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkRW51bUxpc3QzMF8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBmaWVsZEVudW1MaXN0MzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEVudW1MaXN0MzBWYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRFbnVtTGlzdDMwXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF8zMCA9IDMwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0MzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEVudW1MaXN0MzBWYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdDMwSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdDMwXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3QzMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRW51bUxpc3QzMFZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3QzMF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfMzAgPSAzMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdDMwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRFbnVtTGlzdDMwVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3QzMElzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBmaWVsZEVudW1MaXN0MzBfLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkMzJMaXN0MzFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDMyTGlzdDMxXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkMzJMaXN0MzFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDMyTGlzdDMxXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkU2ZpeGVkMzJMaXN0MzFMaXN0KCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRTZml4ZWQzMkxpc3QzMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQzMkxpc3QzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMkxpc3QzMUNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdDMxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdDMxXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTZml4ZWQzMkxpc3QzMSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkMzJMaXN0MzFJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfMzEgPSAzMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDMyTGlzdDMxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQzMkxpc3QzMShpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0MzFfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0MzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNmaXhlZDMyTGlzdDMxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3QzMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNmaXhlZDMyTGlzdDMxXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl9saXN0XzMxID0gMzEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQzMkxpc3QzMSgpIHsKICAgICAgICBmaWVsZFNmaXhlZDMyTGlzdDMxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IGZpZWxkU2ZpeGVkNjRMaXN0MzJfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkNjRMaXN0MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDY0TGlzdDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkU2ZpeGVkNjRMaXN0MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNmaXhlZDY0TGlzdDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkU2ZpeGVkNjRMaXN0MzJMaXN0KCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRTZml4ZWQ2NExpc3QzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMkNvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRTZml4ZWQ2NExpc3QzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRTZml4ZWQ2NExpc3QzMl8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfMzIgPSAzMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDY0TGlzdDMyKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0MzJJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3QzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ZpeGVkNjRMaXN0MzIobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdDMySXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3QzMl8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ZpeGVkNjRMaXN0MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNmaXhlZDY0TGlzdDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3QzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNmaXhlZDY0TGlzdDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF9saXN0XzMyID0gMzIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTZml4ZWQ2NExpc3QzMigpIHsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdDMyXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ludDMyTGlzdDMzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFNpbnQzMkxpc3QzM18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNpbnQzMkxpc3QzM18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZpZWxkU2ludDMyTGlzdDMzTGlzdCgpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF8zMyA9IDMzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQzMkxpc3QzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0MzNDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50MzJMaXN0MzNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ludDMyTGlzdDMzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3QzM18uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ludDMyTGlzdDMzKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50MzJMaXN0MzNJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQzMkxpc3QzM18uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfMzMgPSAzMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQzMkxpc3QzMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDMyTGlzdDMzKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdDMzXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ludDMyTGlzdDMzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRTaW50MzJMaXN0MzMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3QzM0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNpbnQzMkxpc3QzM18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0XzMzID0gMzMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50MzJMaXN0MzMoKSB7CiAgICAgICAgZmllbGRTaW50MzJMaXN0MzNfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTaW50NjRMaXN0MzRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZFNpbnQ2NExpc3QzNF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ludDY0TGlzdDM0XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZFNpbnQ2NExpc3QzNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkU2ludDY0TGlzdDM0TGlzdCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3QzNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF8zNCA9IDM0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNpbnQ2NExpc3QzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50NjRMaXN0MzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNpbnQ2NExpc3QzNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NExpc3QzNChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRTaW50NjRMaXN0MzRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfMzQgPSAzNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDY0TGlzdDM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50NjRMaXN0MzQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0MzRJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3QzNF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0MzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNpbnQ2NExpc3QzNChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdDM0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkU2ludDY0TGlzdDM0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRTaW50NjRMaXN0MzQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3QzNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZFNpbnQ2NExpc3QzNF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0XzM0ID0gMzQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50NjRMaXN0MzQoKSB7CiAgICAgICAgZmllbGRTaW50NjRMaXN0MzRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGREb3VibGVMaXN0UGFja2VkMzVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGREb3VibGVMaXN0UGFja2VkMzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1TGlzdCgpIHsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBmaWVsZF9kb3VibGVfbGlzdF9wYWNrZWRfMzUgPSAzNSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGREb3VibGVMaXN0UGFja2VkMzVDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGREb3VibGVMaXN0UGFja2VkMzVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uZ2V0RG91YmxlKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGREb3VibGVMaXN0UGFja2VkMzVJc011dGFibGUoKTsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRG91YmxlTGlzdFBhY2tlZDM1KGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZERvdWJsZUxpc3RQYWNrZWQzNUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIGZpZWxkX2RvdWJsZV9saXN0X3BhY2tlZF8zNSA9IDM1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGREb3VibGVMaXN0UGFja2VkMzUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkRG91YmxlTGlzdFBhY2tlZDM1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRG91YmxlTGlzdFBhY2tlZDM1Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgZmllbGRfZG91YmxlX2xpc3RfcGFja2VkXzM1ID0gMzUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZERvdWJsZUxpc3RQYWNrZWQzNSgpIHsKICAgICAgICBmaWVsZERvdWJsZUxpc3RQYWNrZWQzNV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGbG9hdExpc3RQYWNrZWQzNklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkRmxvYXRMaXN0UGFja2VkMzZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZsb2F0TGlzdFBhY2tlZDM2XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGbG9hdExpc3RQYWNrZWQzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2TGlzdCgpIHsKICAgICAgICBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRmxvYXRMaXN0UGFja2VkMzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBmaWVsZF9mbG9hdF9saXN0X3BhY2tlZF8zNiA9IDM2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2Xy5nZXRGbG9hdChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXRMaXN0UGFja2VkMzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRGbG9hdExpc3RQYWNrZWQzNihmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGbG9hdExpc3RQYWNrZWQzNl8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgZmllbGRfZmxvYXRfbGlzdF9wYWNrZWRfMzYgPSAzNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEZsb2F0TGlzdFBhY2tlZDM2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRGbG9hdExpc3RQYWNrZWQzNigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEZsb2F0TGlzdFBhY2tlZDM2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IGZpZWxkX2Zsb2F0X2xpc3RfcGFja2VkXzM2ID0gMzYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZsb2F0TGlzdFBhY2tlZDM2KCkgewogICAgICAgIGZpZWxkRmxvYXRMaXN0UGFja2VkMzZfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRJbnQ2NExpc3RQYWNrZWQzN18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldEZpZWxkSW50NjRMaXN0UGFja2VkMzdMaXN0KCkgewogICAgICAgIGZpZWxkSW50NjRMaXN0UGFja2VkMzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRJbnQ2NExpc3RQYWNrZWQzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzN0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRJbnQ2NExpc3RQYWNrZWQzNyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IGZpZWxkX2ludDY0X2xpc3RfcGFja2VkXzM3ID0gMzcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDY0TGlzdFBhY2tlZDM3KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkSW50NjRMaXN0UGFja2VkMzdJc011dGFibGUoKTsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NExpc3RQYWNrZWQzNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkSW50NjRMaXN0UGFja2VkMzcobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDY0TGlzdFBhY2tlZDM3SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQ2NExpc3RQYWNrZWQzN18uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkSW50NjRMaXN0UGFja2VkMzcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEludDY0TGlzdFBhY2tlZDM3KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRJbnQ2NExpc3RQYWNrZWQzN0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEludDY0TGlzdFBhY2tlZDM3Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBmaWVsZF9pbnQ2NF9saXN0X3BhY2tlZF8zNyA9IDM3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQ2NExpc3RQYWNrZWQzNygpIHsKICAgICAgICBmaWVsZEludDY0TGlzdFBhY2tlZDM3XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRVaW50NjRMaXN0UGFja2VkMzhfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRVaW50NjRMaXN0UGFja2VkMzhMaXN0KCkgewogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IGZpZWxkX3VpbnQ2NF9saXN0X3BhY2tlZF8zOCA9IDM4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBmaWVsZF91aW50NjRfbGlzdF9wYWNrZWRfMzggPSAzOCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkVWludDY0TGlzdFBhY2tlZDM4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50NjRMaXN0UGFja2VkMzhJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRVaW50NjRMaXN0UGFja2VkMzggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkVWludDY0TGlzdFBhY2tlZDM4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkVWludDY0TGlzdFBhY2tlZDM4Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgZmllbGRfdWludDY0X2xpc3RfcGFja2VkXzM4ID0gMzggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQ2NExpc3RQYWNrZWQzOCgpIHsKICAgICAgICBmaWVsZFVpbnQ2NExpc3RQYWNrZWQzOF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEludDMyTGlzdFBhY2tlZDM5XyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEludDMyTGlzdFBhY2tlZDM5Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRJbnQzMkxpc3RQYWNrZWQzOUxpc3QoKSB7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZEludDMyTGlzdFBhY2tlZDM5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEludDMyTGlzdFBhY2tlZDM5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkSW50MzJMaXN0UGFja2VkMzkoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEludDMyTGlzdFBhY2tlZDM5KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRJbnQzMkxpc3RQYWNrZWQzOUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZmllbGRfaW50MzJfbGlzdF9wYWNrZWRfMzkgPSAzOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkSW50MzJMaXN0UGFja2VkMzkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEludDMyTGlzdFBhY2tlZDM5KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRJbnQzMkxpc3RQYWNrZWQzOV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRJbnQzMkxpc3RQYWNrZWQzOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkSW50MzJMaXN0UGFja2VkMzkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZEludDMyTGlzdFBhY2tlZDM5SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZpZWxkX2ludDMyX2xpc3RfcGFja2VkXzM5ID0gMzkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEludDMyTGlzdFBhY2tlZDM5KCkgewogICAgICAgIGZpZWxkSW50MzJMaXN0UGFja2VkMzlfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwTGlzdCgpIHsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgZmllbGRfZml4ZWQ2NF9saXN0X3BhY2tlZF80MCA9IDQwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IGZpZWxkX2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDAgPSA0MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBJc011dGFibGUoKTsKICAgICAgICBmaWVsZEZpeGVkNjRMaXN0UGFja2VkNDBfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRml4ZWQ2NExpc3RQYWNrZWQ0MF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBmaWVsZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwID0gNDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAoKSB7CiAgICAgICAgZmllbGRGaXhlZDY0TGlzdFBhY2tlZDQwXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IG1ha2VNdXRhYmxlQ29weShmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxTGlzdCgpIHsKICAgICAgICBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgZmllbGRfZml4ZWQzMl9saXN0X3BhY2tlZF80MSA9IDQxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGZpZWxkX2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDEgPSA0MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MShpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkRml4ZWQzMkxpc3RQYWNrZWQ0MV8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBmaWVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxID0gNDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkMzJMaXN0UGFja2VkNDEoKSB7CiAgICAgICAgZmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmaWVsZEJvb2xMaXN0UGFja2VkNDJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIWZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRCb29sTGlzdFBhY2tlZDQyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0Mkxpc3QoKSB7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkQm9vbExpc3RQYWNrZWQ0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRCb29sTGlzdFBhY2tlZDQyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIGZpZWxkX2Jvb2xfbGlzdF9wYWNrZWRfNDIgPSA0MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkQm9vbExpc3RQYWNrZWQ0MihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRCb29sTGlzdFBhY2tlZDQyXy5nZXRCb29sZWFuKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyID0gNDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQm9vbExpc3RQYWNrZWQ0MigKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZEJvb2xMaXN0UGFja2VkNDJJc011dGFibGUoKTsKICAgICAgICBmaWVsZEJvb2xMaXN0UGFja2VkNDJfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRCb29sTGlzdFBhY2tlZDQyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRCb29sTGlzdFBhY2tlZDQyKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRCb29sTGlzdFBhY2tlZDQySXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRCb29sTGlzdFBhY2tlZDQyXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZpZWxkQm9vbExpc3RQYWNrZWQ0MiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkQm9vbExpc3RQYWNrZWQ0MigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkQm9vbExpc3RQYWNrZWQ0MklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmaWVsZEJvb2xMaXN0UGFja2VkNDJfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgZmllbGRfYm9vbF9saXN0X3BhY2tlZF80MiA9IDQyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRCb29sTGlzdFBhY2tlZDQyKCkgewogICAgICAgIGZpZWxkQm9vbExpc3RQYWNrZWQ0Ml8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18gPSBtYWtlTXV0YWJsZUNvcHkoZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M0xpc3QoKSB7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgZmllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzID0gNDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZmllbGRVaW50MzJMaXN0UGFja2VkNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkVWludDMyTGlzdFBhY2tlZDQzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MygKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkVWludDMyTGlzdFBhY2tlZDQzSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIGZpZWxkX3VpbnQzMl9saXN0X3BhY2tlZF80MyA9IDQzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRVaW50MzJMaXN0UGFja2VkNDMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0M18uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkVWludDMyTGlzdFBhY2tlZDQzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRVaW50MzJMaXN0UGFja2VkNDNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmllbGRVaW50MzJMaXN0UGFja2VkNDNfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBmaWVsZF91aW50MzJfbGlzdF9wYWNrZWRfNDMgPSA0MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDMyTGlzdFBhY2tlZDQzKCkgewogICAgICAgIGZpZWxkVWludDMyTGlzdFBhY2tlZDQzXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0XyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4oZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBnZXRGaWVsZEVudW1MaXN0UGFja2VkNDRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4oZmllbGRFbnVtTGlzdFBhY2tlZDQ0XywgZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBmaWVsZF9lbnVtX2xpc3RfcGFja2VkXzQ0ID0gNDQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGRFbnVtTGlzdFBhY2tlZDQ0X2NvbnZlcnRlcl8uY29udmVydChmaWVsZEVudW1MaXN0UGFja2VkNDRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRFbnVtTGlzdFBhY2tlZDQ0KAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUZpZWxkRW51bUxpc3RQYWNrZWQ0NElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRFbnVtTGlzdFBhY2tlZDQ0KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBmaWVsZEVudW1MaXN0UGFja2VkNDQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEVudW1MaXN0UGFja2VkNDQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRFbnVtTGlzdFBhY2tlZDQ0KCkgewogICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0UGFja2VkNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlTGlzdCgpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZEVudW1MaXN0UGFja2VkNDRfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZmllbGRfZW51bV9saXN0X3BhY2tlZF80NCA9IDQ0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIGZpZWxkRW51bUxpc3RQYWNrZWQ0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRW51bUxpc3RQYWNrZWQ0NFZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVGaWVsZEVudW1MaXN0UGFja2VkNDRJc011dGFibGUoKTsKICAgICAgICBmaWVsZEVudW1MaXN0UGFja2VkNDRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZmllbGRFbnVtTGlzdFBhY2tlZDQ0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRFbnVtTGlzdFBhY2tlZDQ0VmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRFbnVtTGlzdFBhY2tlZDQ0Xy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGZpZWxkX2VudW1fbGlzdF9wYWNrZWRfNDQgPSA0NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBmaWVsZEVudW1MaXN0UGFja2VkNDQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZEVudW1MaXN0UGFja2VkNDRWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRmllbGRFbnVtTGlzdFBhY2tlZDQ0SXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIGZpZWxkRW51bUxpc3RQYWNrZWQ0NF8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NUlzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfbGlzdF9wYWNrZWRfNDUgPSA0NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyX2xpc3RfcGFja2VkXzQ1ID0gNDUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDMyTGlzdFBhY2tlZDQ1KCkgewogICAgICAgIGZpZWxkU2ZpeGVkMzJMaXN0UGFja2VkNDVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nkxpc3QoKSB7CiAgICAgICAgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfNDYgPSA0NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NklzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0Nihsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTZml4ZWQ2NExpc3RQYWNrZWQ0NiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0X2xpc3RfcGFja2VkXzQ2ID0gNDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2KCkgewogICAgICAgIGZpZWxkU2ZpeGVkNjRMaXN0UGFja2VkNDZfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDdMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIGZpZWxkX3NpbnQzMl9saXN0X3BhY2tlZF80NyA9IDQ3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTaW50MzJMaXN0UGFja2VkNDcoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N0lzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWRfNDcgPSA0NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRTaW50MzJMaXN0UGFja2VkNDcoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRTaW50MzJMaXN0UGFja2VkNDdfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50MzJMaXN0UGFja2VkNDcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgZmllbGRfc2ludDMyX2xpc3RfcGFja2VkXzQ3ID0gNDcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMkxpc3RQYWNrZWQ0NygpIHsKICAgICAgICBmaWVsZFNpbnQzMkxpc3RQYWNrZWQ0N18gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZmllbGRTaW50NjRMaXN0UGFja2VkNDhfID0gbWFrZU11dGFibGVDb3B5KGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0RmllbGRTaW50NjRMaXN0UGFja2VkNDhMaXN0KCkgewogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IGZpZWxkX3NpbnQ2NF9saXN0X3BhY2tlZF80OCA9IDQ4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OENvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBmaWVsZF9zaW50NjRfbGlzdF9wYWNrZWRfNDggPSA0OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRmllbGRTaW50NjRMaXN0UGFja2VkNDhJc011dGFibGUoKTsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZmllbGRTaW50NjRMaXN0UGFja2VkNDggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgZmllbGRfc2ludDY0X2xpc3RfcGFja2VkXzQ4ID0gNDggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OCgpIHsKICAgICAgICBmaWVsZFNpbnQ2NExpc3RQYWNrZWQ0OF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIGZpZWxkX2RvdWJsZV81MyA9IDUzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZERvdWJsZTUzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRG91YmxlNTMoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDUzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZERvdWJsZTUzLgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZERvdWJsZTUzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1MykgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuRG91YmxlKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBmaWVsZF9kb3VibGVfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGREb3VibGU1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRG91YmxlNTMoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTM7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgZmllbGRfZG91YmxlXzUzID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkRG91YmxlNTMoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDUzKSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZsb2F0NTQoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBmaWVsZF9mbG9hdF81NCA9IDU0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRGbG9hdDU0LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkRmxvYXQ1NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTQpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkZsb2F0KSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEY7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IGZpZWxkX2Zsb2F0XzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRmxvYXQ1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRmxvYXQ1NChmbG9hdCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU0OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgZmllbGRfZmxvYXRfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdDU0KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NCkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBmaWVsZF9pbnQ2NF81NSA9IDU1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0NTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQ2NDU1KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1NTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50NjQ1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkSW50NjQ1NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgZmllbGRfaW50NjRfNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQ2NDU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQ2NDU1KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1NTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGZpZWxkX2ludDY0XzU1ID0gNTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50NjQ1NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTUpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NDU2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0NTYoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NDU2LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRVaW50NjQ1NigpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTYpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IGZpZWxkX3VpbnQ2NF81NiA9IDU2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZFVpbnQ2NDU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjQ1Nihsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTY7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgZmllbGRfdWludDY0XzU2ID0gNTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDY0NTYoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU2KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZpZWxkX2ludDMyXzU3ID0gNTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyNTcoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU3OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZF9pbnQzMl81NyA9IDU3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMjU3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGaWVsZEludDMyNTcoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU3KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGRJbnQzMjU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMjU3KGludCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDU3OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGRfaW50MzJfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMjU3KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA1NykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGaXhlZDY0NTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRGaXhlZDY0NTgoKSB7CiAgICAgICAgcmV0dXJuIHRlc3RPbmVvZkNhc2VfID09IDU4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IGZpZWxkX2ZpeGVkNjRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRml4ZWQ2NDU4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRGaXhlZDY0NTgoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU4KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEw7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZEZpeGVkNjQ1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRml4ZWQ2NDU4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA1ODsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgZmllbGRfZml4ZWQ2NF81OCA9IDU4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEZpeGVkNjQ1OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNTgpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRml4ZWQzMjU5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRml4ZWQzMjU5KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA1OTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZpeGVkMzI1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRGaXhlZDMyNTkoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBmaWVsZF9maXhlZDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkRml4ZWQzMjU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGaXhlZDMyNTkoaW50IHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNTk7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIGZpZWxkX2ZpeGVkMzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGaXhlZDMyNTkoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDU5KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJvb2w2MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJvb2w2MCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgZmllbGRfYm9vbF82MCA9IDYwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCb29sNjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZEJvb2w2MCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjApIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkJvb2xlYW4pIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQm9vbDYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sNjAoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYwOwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBmaWVsZF9ib29sXzYwID0gNjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQm9vbDYwKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MCkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nNjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZzYxKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZpZWxkX3N0cmluZ182MSA9IDYxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmc2MS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRTdHJpbmc2MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MSkgewogICAgICAgICAgcmVmID0gdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZmllbGRTdHJpbmc2MS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RmllbGRTdHJpbmc2MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICByZWYgPSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYxKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU3RyaW5nNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZzYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2MTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmaWVsZF9zdHJpbmdfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmc2MSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjEpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZmllbGRfc3RyaW5nXzYxID0gNjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmaWVsZFN0cmluZzYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRTdHJpbmc2MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjE7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGZpZWxkTWVzc2FnZTYyQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNZXNzYWdlNjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1lc3NhZ2U2MigpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRNZXNzYWdlNjIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNZXNzYWdlNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB0ZXN0T25lb2ZfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2U2Mihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1lc3NhZ2U2MigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDYyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkTWVzc2FnZTYyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MiAmJgogICAgICAgICAgICAgIHRlc3RPbmVvZl8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB0ZXN0T25lb2ZfKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNZXNzYWdlNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjIpIHsKICAgICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBnZXRGaWVsZE1lc3NhZ2U2MkJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWVzc2FnZTYyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIGZpZWxkX21lc3NhZ2VfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0RmllbGRNZXNzYWdlNjJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKCh0ZXN0T25lb2ZDYXNlXyA9PSA2MikgJiYgKGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBmaWVsZE1lc3NhZ2U2MkJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYyKSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB0ZXN0T25lb2ZfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUgZmllbGRfbWVzc2FnZV82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZE1lc3NhZ2U2MkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRNZXNzYWdlNjJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoISh0ZXN0T25lb2ZDYXNlXyA9PSA2MikpIHsKICAgICAgICAgICAgdGVzdE9uZW9mXyA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB0ZXN0T25lb2ZfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWVzc2FnZTYyQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzNjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCeXRlczYzKCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2MzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZmllbGRfYnl0ZXNfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXM2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRCeXRlczYzKCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2MykgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZpZWxkX2J5dGVzXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkQnl0ZXM2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQnl0ZXM2Myhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjM7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmaWVsZF9ieXRlc182MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJ5dGVzNjMoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDYzKSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBmaWVsZF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQzMjY0KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzI2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRVaW50MzI2NCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjQpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgZmllbGRfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkVWludDMyNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQzMjY0KGludCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY0OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIGZpZWxkX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQzMjY0KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NCkgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBmaWVsZF9zZml4ZWQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFNmaXhlZDMyNjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTZml4ZWQzMjY1KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgZmllbGRfc2ZpeGVkMzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ZpeGVkMzI2NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTZml4ZWQzMjY1KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkMzI2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkMzI2NShpbnQgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2NTsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIGZpZWxkX3NmaXhlZDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkU2ZpeGVkMzI2NSgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjUpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgZmllbGRfc2ZpeGVkNjRfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTZml4ZWQ2NDY2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkU2ZpeGVkNjQ2NigpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjY7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFNmaXhlZDY0NjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY2KSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSB0ZXN0T25lb2ZfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEw7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IGZpZWxkX3NmaXhlZDY0XzY2ID0gNjY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ZpeGVkNjQ2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU2ZpeGVkNjQ2Nihsb25nIHZhbHVlKSB7CgogICAgICAgIHRlc3RPbmVvZkNhc2VfID0gNjY7CiAgICAgICAgdGVzdE9uZW9mXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBmaWVsZF9zZml4ZWQ2NF82NiA9IDY2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNmaXhlZDY0NjYoKSB7CiAgICAgICAgaWYgKHRlc3RPbmVvZkNhc2VfID09IDY2KSB7CiAgICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICB0ZXN0T25lb2ZfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBmaWVsZF9zaW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTaW50MzI2NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFNpbnQzMjY3KCkgewogICAgICAgIHJldHVybiB0ZXN0T25lb2ZDYXNlXyA9PSA2NzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRTaW50MzI2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRTaW50MzI2NygpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjcpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIHRlc3RPbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgZmllbGRfc2ludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDMyNjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQzMjY3KGludCB2YWx1ZSkgewoKICAgICAgICB0ZXN0T25lb2ZDYXNlXyA9IDY3OwogICAgICAgIHRlc3RPbmVvZl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIGZpZWxkX3NpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFNpbnQzMjY3KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2NykgewogICAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSAwOwogICAgICAgICAgdGVzdE9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU2ludDY0NjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRTaW50NjQ2OCgpIHsKICAgICAgICByZXR1cm4gdGVzdE9uZW9mQ2FzZV8gPT0gNjg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU2ludDY0NjguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZFNpbnQ2NDY4KCkgewogICAgICAgIGlmICh0ZXN0T25lb2ZDYXNlXyA9PSA2OCkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuTG9uZykgdGVzdE9uZW9mXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDBMOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgZmllbGRfc2ludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkU2ludDY0NjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFNpbnQ2NDY4KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgdGVzdE9uZW9mQ2FzZV8gPSA2ODsKICAgICAgICB0ZXN0T25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBmaWVsZF9zaW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTaW50NjQ2OCgpIHsKICAgICAgICBpZiAodGVzdE9uZW9mQ2FzZV8gPT0gNjgpIHsKICAgICAgICAgIHRlc3RPbmVvZkNhc2VfID0gMDsKICAgICAgICAgIHRlc3RPbmVvZl8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8zTWVzc2FnZUxpdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBQcm90bzNNZXNzYWdlTGl0ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM01lc3NhZ2VMaXRlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM01lc3NhZ2VMaXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBQcm90bzNFbXB0eUxpdGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM0VtcHR5TGl0ZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM0VtcHR5TGl0ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFByb3RvM0VtcHR5TGl0ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zRW1wdHlMaXRlKQogICAgICBQcm90bzNFbXB0eUxpdGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFByb3RvM0VtcHR5TGl0ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzNFbXB0eUxpdGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBQcm90bzNFbXB0eUxpdGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUHJvdG8zRW1wdHlMaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlMaXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zRW1wdHlMaXRlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM0VtcHR5TGl0ZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5TGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNFbXB0eUxpdGVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNFbXB0eUxpdGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNFbXB0eUxpdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNFbXB0eUxpdGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zRW1wdHlMaXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNFbXB0eUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzNFbXB0eUxpdGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8zRW1wdHlMaXRlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUHJvdG8zRW1wdHlMaXRlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zRW1wdHlMaXRlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM0VtcHR5TGl0ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM0VtcHR5TGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xCb29sMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwQm9vbEJvb2wxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sQnl0ZXMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xCeXRlczIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xEb3VibGUzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwQm9vbERvdWJsZTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwQm9vbERvdWJsZTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEJvb2xEb3VibGUzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xFbnVtNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEVudW00KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEVudW00VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDMyNSgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkNjQ2KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEJvb2xGbG9hdDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEJvb2xGbG9hdDdPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEludDMyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbEludDY0OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sSW50NjQ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ludDY0MTRPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU3RyaW5nMTUoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgYm9vbGVhbiBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBCb29sVWludDY0MTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xVaW50NjQxNygKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyVWludDMyMzMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qm9vbDM1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJCeXRlczUzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJFbnVtNTUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMySW50NjQ2MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJNZXNzYWdlNjEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyVWludDMyNjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDMyVWludDY0NjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDY0XzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Qm9vbDY5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcEludDY0Qm9vbDY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRCeXRlczcwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjREb3VibGU3MUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGaXhlZDMyNzMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRGaXhlZDY0NzQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ludDY0ODIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFN0cmluZzgzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcEludDY0VWludDY0ODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkVudW04OSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDY0Xzk5ID0gOTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCeXRlczEyMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQ2NF8xMjUgPSAxMjU7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJJbnQzMjEyNygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJVaW50MzIxMzUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCb29sMTM3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQ2NF9ieXRlc18xMzggPSAxMzg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRCeXRlczEzOCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5ID0gMTM5OzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRFbnVtMTQwKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGbG9hdDE0MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDY0MTUzKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nSW50NjQxNjIoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfdWludDMyX2Jvb2xfMTcxID0gMTcxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQnl0ZXMxNzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBkb3VibGUgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICovCiAgICBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTaW50MzIxODMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDMyMTg2KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qm9vbDE4OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQzMjE5NSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDY0MjAxKAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcykKICAgICAgUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBQcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBQcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpOwogICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgIGNhc2UgMTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpOwogICAgICAgIGNhc2UgMTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgIGNhc2UgMTg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICBjYXNlIDE5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpOwogICAgICAgIGNhc2UgMjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgIGNhc2UgMjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICBjYXNlIDIyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCk7CiAgICAgICAgY2FzZSAyMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgY2FzZSAyNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKTsKICAgICAgICBjYXNlIDI2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgIGNhc2UgMjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICBjYXNlIDI4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpOwogICAgICAgIGNhc2UgMjk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgY2FzZSAzMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgY2FzZSAzMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCk7CiAgICAgICAgY2FzZSAzMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgY2FzZSAzMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgY2FzZSAzNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCk7CiAgICAgICAgY2FzZSAzNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgIGNhc2UgMzY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgY2FzZSAzNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCk7CiAgICAgICAgY2FzZSAzODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgIGNhc2UgMzk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICBjYXNlIDQwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCk7CiAgICAgICAgY2FzZSA0MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICBjYXNlIDQyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgIGNhc2UgNDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAgICAgY2FzZSA0NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgIGNhc2UgNDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgY2FzZSA0NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKTsKICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICBjYXNlIDQ4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICBjYXNlIDQ5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKTsKICAgICAgICBjYXNlIDUwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICBjYXNlIDUxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICBjYXNlIDUyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpOwogICAgICAgIGNhc2UgNTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgIGNhc2UgNTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICBjYXNlIDU1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpOwogICAgICAgIGNhc2UgNTY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgY2FzZSA1NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICBjYXNlIDU4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKTsKICAgICAgICBjYXNlIDU5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICBjYXNlIDYwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICBjYXNlIDYxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpOwogICAgICAgIGNhc2UgNjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgIGNhc2UgNjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgIGNhc2UgNjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKTsKICAgICAgICBjYXNlIDY1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgY2FzZSA2NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgIGNhc2UgNjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKTsKICAgICAgICBjYXNlIDY4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgY2FzZSA2OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICBjYXNlIDcwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKTsKICAgICAgICBjYXNlIDcxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgY2FzZSA3MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICBjYXNlIDczOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgY2FzZSA3NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgY2FzZSA3NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCk7CiAgICAgICAgY2FzZSA3NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgY2FzZSA3ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICBjYXNlIDc5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKTsKICAgICAgICBjYXNlIDgwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICBjYXNlIDgxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgY2FzZSA4MjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpOwogICAgICAgIGNhc2UgODM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICBjYXNlIDg0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgY2FzZSA4NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpOwogICAgICAgIGNhc2UgODY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgY2FzZSA4NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgY2FzZSA4ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpOwogICAgICAgIGNhc2UgODk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgY2FzZSA5MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICBjYXNlIDkxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpOwogICAgICAgIGNhc2UgOTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgIGNhc2UgOTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgIGNhc2UgOTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpOwogICAgICAgIGNhc2UgOTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgY2FzZSA5NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgY2FzZSA5NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCk7CiAgICAgICAgY2FzZSA5ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgIGNhc2UgOTk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICBjYXNlIDEwMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKTsKICAgICAgICBjYXNlIDEwMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICBjYXNlIDEwMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCk7CiAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICBjYXNlIDEwNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICBjYXNlIDEwNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCk7CiAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgIGNhc2UgMTA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICBjYXNlIDEwOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpOwogICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICBjYXNlIDExMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCk7CiAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICBjYXNlIDExNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgIGNhc2UgMTE1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpOwogICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgIGNhc2UgMTE3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgIGNhc2UgMTE4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpOwogICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgIGNhc2UgMTIwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgY2FzZSAxMjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCk7CiAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgIGNhc2UgMTIzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgY2FzZSAxMjQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKTsKICAgICAgICBjYXNlIDEyNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgIGNhc2UgMTI2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgIGNhc2UgMTI3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpOwogICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgIGNhc2UgMTI5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgY2FzZSAxMzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgY2FzZSAxMzI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgIGNhc2UgMTMzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgY2FzZSAxMzU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgIGNhc2UgMTM2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgIGNhc2UgMTM4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgIGNhc2UgMTM5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgIGNhc2UgMTQxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgY2FzZSAxNDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKTsKICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICBjYXNlIDE0NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICBjYXNlIDE0NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKTsKICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgIGNhc2UgMTQ3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgIGNhc2UgMTQ4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpOwogICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICBjYXNlIDE1MDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgY2FzZSAxNTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpOwogICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICBjYXNlIDE1MzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgY2FzZSAxNTQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKTsKICAgICAgICBjYXNlIDE1NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICBjYXNlIDE1NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgY2FzZSAxNTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKTsKICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgIGNhc2UgMTU5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgY2FzZSAxNjA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgY2FzZSAxNjI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgY2FzZSAxNjM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKTsKICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICBjYXNlIDE2NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICBjYXNlIDE2NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCk7CiAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgIGNhc2UgMTY4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICBjYXNlIDE2OToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCk7CiAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgIGNhc2UgMTcxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgY2FzZSAxNzI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCk7CiAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgIGNhc2UgMTc0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgY2FzZSAxNzU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgIGNhc2UgMTc3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgIGNhc2UgMTc4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpOwogICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgIGNhc2UgMTgwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgY2FzZSAxODE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCk7CiAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgY2FzZSAxODM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgIGNhc2UgMTg0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKTsKICAgICAgICBjYXNlIDE4NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgY2FzZSAxODY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgIGNhc2UgMTg3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKTsKICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgIGNhc2UgMTg5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgIGNhc2UgMTkwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKTsKICAgICAgICBjYXNlIDE5MToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgIGNhc2UgMTkyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgY2FzZSAxOTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKTsKICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICBjYXNlIDE5NToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICBjYXNlIDE5NjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKTsKICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgIGNhc2UgMTk4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgIGNhc2UgMTk5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpOwogICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICBjYXNlIDIwMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICBjYXNlIDIwNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0JPT0xfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEJvb2wxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xCb29sMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEJvb2xCb29sMU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0JZVEVTXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwQm9vbEJ5dGVzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sQnl0ZXMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEJ5dGVzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEJ5dGVzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0RPVUJMRV8zX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sRG91YmxlM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRG91YmxlM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbERvdWJsZTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xEb3VibGUzKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwQm9vbERvdWJsZTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9FTlVNXzRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sRW51bTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xFbnVtNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwQm9vbEVudW00VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xFbnVtNCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBCb29sRW51bTRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwQm9vbEVudW00T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEJvb2xFbnVtNE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00VmFsdWVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9GSVhFRDMyXzVfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEZpeGVkMzI1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xGaXhlZDMyNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQ2NDZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkNjQ2KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX0ZMT0FUXzdfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBCb29sRmxvYXQ3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xGbG9hdDdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sRmxvYXQ3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xGbG9hdDdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfSU5UMzJfOF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbEludDMyOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQzMjhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xJbnQzMjhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX2ludDMyXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQzMjhPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbEludDY0OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQ2NDlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50NjQ5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50NjQ5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEludDY0OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sSW50NjQ5T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9NRVNTQUdFXzEwX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbE1lc3NhZ2UxMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfQk9PTF9TRklYRUQzMl8xMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1NGSVhFRDY0XzEyX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sU2ZpeGVkNjQxMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ZpeGVkNjQxMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpIHsKICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1NJTlQzMl8xM19GSUVMRF9OVU1CRVIgPSAxMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU2ludDMyMTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50MzIxM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTaW50MzIxM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU0lOVDY0XzE0X0ZJRUxEX05VTUJFUiA9IDE0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFNpbnQ2NDE0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sU2ludDY0MTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTaW50NjQxNF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ludDY0MTQoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfU1RSSU5HXzE1X0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEJvb2xTdHJpbmcxNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwQm9vbFN0cmluZzE1T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9CT09MX1VJTlQzMl8xNl9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbFVpbnQzMjE2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sVWludDMyMTZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50MzIxNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0JPT0xfVUlOVDY0XzE3X0ZJRUxEX05VTUJFUiA9IDE3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sVWludDY0MTdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwQm9vbFVpbnQ2NDE3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICBpZiAoZmllbGRNYXBCb29sVWludDY0MTdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfQk9PTF8xOF9GSUVMRF9OVU1CRVIgPSAxODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCb29sMThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ib29sXzE4ID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVIgPSAxOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkMzJCeXRlczE5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0RPVUJMRV8yMF9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0VOVU1fMjFfRklFTERfTlVNQkVSID0gMjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRW51bTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVEMzJfMjJfRklFTERfTlVNQkVSID0gMjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9GSVhFRDY0XzIzX0ZJRUxEX05VTUJFUiA9IDIzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQ2NF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX0ZMT0FUXzI0X0ZJRUxEX05VTUJFUiA9IDI0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGbG9hdDI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9JTlQzMl8yNV9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMySW50MzIyNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMySW50MzIyNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50MzIyNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVEMzJfSU5UNjRfMjZfRklFTERfTlVNQkVSID0gMjY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50NjRfMjYgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUiA9IDI3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDMyXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TRklYRUQ2NF8yOV9GSUVMRF9OVU1CRVIgPSAyOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDY0XzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NJTlQzMl8zMF9GSUVMRF9OVU1CRVIgPSAzMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9TSU5UNjRfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDY0MzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDY0MzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1NUUklOR18zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDMyX1VJTlQzMl8zM19GSUVMRF9OVU1CRVIgPSAzMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQzMl9VSU5UNjRfMzRfRklFTERfTlVNQkVSID0gMzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkMzJVaW50NjQzNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDY0MzRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDY0MzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0JPT0xfMzVfRklFTERfTlVNQkVSID0gMzU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBGaXhlZDY0Qm9vbDM1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0JZVEVTXzM2X0ZJRUxEX05VTUJFUiA9IDM2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ieXRlc18zNiA9IDM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0RPVUJMRV8zN19GSUVMRF9OVU1CRVIgPSAzNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjREb3VibGUzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzcgPSAzNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9FTlVNXzM4X0ZJRUxEX05VTUJFUiA9IDM4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0RW51bTM4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRFbnVtMzhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUiA9IDM5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQzMl8zOSA9IDM5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0ZJWEVENjRfNDBfRklFTERfTlVNQkVSID0gNDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X0ZMT0FUXzQxX0ZJRUxEX05VTUJFUiA9IDQxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSID0gNDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9JTlQ2NF80M19GSUVMRF9OVU1CRVIgPSA0MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9NRVNTQUdFXzQ0X0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQzMl80NV9GSUVMRF9OVU1CRVIgPSA0NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NGSVhFRDY0XzQ2X0ZJRUxEX05VTUJFUiA9IDQ2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpIHsKICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1NJTlQzMl80N19GSUVMRF9OVU1CRVIgPSA0NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfU0lOVDY0XzQ4X0ZJRUxEX05VTUJFUiA9IDQ4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfU1RSSU5HXzQ5X0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9GSVhFRDY0X1VJTlQzMl81MF9GSUVMRF9OVU1CRVIgPSA1MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50MzI1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0ZJWEVENjRfVUlOVDY0XzUxX0ZJRUxEX05VTUJFUiA9IDUxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDY0NTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0JPT0xfNTJfRklFTERfTlVNQkVSID0gNTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQm9vbDUyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyQm9vbDUyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJvb2w1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkJvb2w1MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJCb29sNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50MzJCb29sNTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ib29sXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDMyQm9vbDUyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfQllURVNfNTNfRklFTERfTlVNQkVSID0gNTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBJbnQzMkJ5dGVzNTNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkJ5dGVzNTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJCeXRlczUzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9ET1VCTEVfNTRfRklFTERfTlVNQkVSID0gNTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRG91YmxlNTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEludDMyRG91YmxlNTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyRG91YmxlNTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9FTlVNXzU1X0ZJRUxEX05VTUJFUiA9IDU1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkVudW01NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRW51bTU1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50MzJFbnVtNTVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9GSVhFRDMyXzU2X0ZJRUxEX05VTUJFUiA9IDU2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfRklYRUQ2NF81N19GSUVMRF9OVU1CRVIgPSA1NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDY0XzU3ID0gNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9GTE9BVF81OF9GSUVMRF9OVU1CRVIgPSA1ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJGbG9hdDU4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGbG9hdDU4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwSW50MzJGbG9hdDU4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJGbG9hdDU4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZsb2F0NThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfSU5UMzJfNTlfRklFTERfTlVNQkVSID0gNTk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMySW50MzI1OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDMyNTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMkludDMyNTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMySW50MzI1OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMySW50MzI1OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkludDMyNTkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDMyX0lOVDY0XzYwX0ZJRUxEX05VTUJFUiA9IDYwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMySW50NjQ2MF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMySW50NjQ2ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfTUVTU0FHRV82MV9GSUVMRF9OVU1CRVIgPSA2MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1hcEludDMyTWVzc2FnZTYxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyTWVzc2FnZTYxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TRklYRUQzMl82Ml9GSUVMRF9OVU1CRVIgPSA2MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVENjRfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TSU5UMzJfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50MzI2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU2ludDMyNjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDMyNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQzMjY0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlNpbnQzMjY0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfU0lOVDY0XzY1X0ZJRUxEX05VTUJFUiA9IDY1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQ2NF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9TVFJJTkdfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU3RyaW5nNjZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyU3RyaW5nNjZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTdHJpbmc2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQzMl9VSU5UMzJfNjdfRklFTERfTlVNQkVSID0gNjc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDMyNjdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlVpbnQzMjY3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UMzJfVUlOVDY0XzY4X0ZJRUxEX05VTUJFUiA9IDY4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQzMlVpbnQ2NDY4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50NjQ2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDY0NjhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9CT09MXzY5X0ZJRUxEX05VTUJFUiA9IDY5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJvb2w2OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRCb29sNjlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCb29sNjlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qm9vbDY5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50NjRCb29sNjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50NjRCb29sNjlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9CWVRFU183MF9GSUVMRF9OVU1CRVIgPSA3MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCeXRlczcwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NEJ5dGVzNzBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qnl0ZXM3MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRCeXRlczcwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEJ5dGVzNzAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ludDY0X2J5dGVzXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50NjRCeXRlczcwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9ET1VCTEVfNzFfRklFTERfTlVNQkVSID0gNzE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjREb3VibGU3MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50NjREb3VibGU3MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRU5VTV83Ml9GSUVMRF9OVU1CRVIgPSA3MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0RW51bTcyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0RW51bTcyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEVudW03MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RW51bTcyXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQ2NEVudW03Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfRklYRUQzMl83M19GSUVMRF9OVU1CRVIgPSA3MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9GSVhFRDY0Xzc0X0ZJRUxEX05VTUJFUiA9IDc0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVIgPSA3NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0RmxvYXQ3NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGbG9hdDc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9mbG9hdF83NSA9IDc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X0lOVDMyXzc2X0ZJRUxEX05VTUJFUiA9IDc2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0SW50MzI3Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQzMjc2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfSU5UNjRfNzdfRklFTERfTlVNQkVSID0gNzc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEludDY0NzdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0SW50NjQ3N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfTUVTU0FHRV83OF9GSUVMRF9OVU1CRVIgPSA3ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVEMzJfNzlfRklFTERfTlVNQkVSID0gNzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TRklYRUQ2NF84MF9GSUVMRF9OVU1CRVIgPSA4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9TSU5UMzJfODFfRklFTERfTlVNQkVSID0gODE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50MzI4MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDMyODFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQzMl84MSA9IDgxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDMyODFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NJTlQ2NF84Ml9GSUVMRF9OVU1CRVIgPSA4MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50NjQ4MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVIgPSA4MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSB7CiAgICAgIGlmIChmaWVsZE1hcEludDY0U3RyaW5nODNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcEludDY0U3RyaW5nODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFN0cmluZzgzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFN0cmluZzgzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9JTlQ2NF9VSU5UMzJfODRfRklFTERfTlVNQkVSID0gODQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0VWludDMyODREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQzMjg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50MzI4NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDMyXzg0ID0gODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0VWludDMyODQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX0lOVDY0X1VJTlQ2NF84NV9GSUVMRF9OVU1CRVIgPSA4NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkgewogICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRVaW50NjQ4NSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDY0ODVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0VWludDY0ODVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0JPT0xfODZfRklFTERfTlVNQkVSID0gODY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJvb2w4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Jvb2xfODYgPSA4Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfQllURVNfODdfRklFTERfTlVNQkVSID0gODc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9ET1VCTEVfODhfRklFTERfTlVNQkVSID0gODg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUiA9IDg5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkVudW04OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9GSVhFRDMyXzkwX0ZJRUxEX05VTUJFUiA9IDkwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkNjRfOTEgPSA5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9GTE9BVF85Ml9GSUVMRF9OVU1CRVIgPSA5MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfSU5UMzJfOTNfRklFTERfTlVNQkVSID0gOTM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUiA9IDk0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfTUVTU0FHRV85NV9GSUVMRF9OVU1CRVIgPSA5NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQzMl85Nl9GSUVMRF9OVU1CRVIgPSA5NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0ZJWEVENjRfOTdfRklFTERfTlVNQkVSID0gOTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TSU5UMzJfOThfRklFTERfTlVNQkVSID0gOTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDY0Xzk5X0ZJRUxEX05VTUJFUiA9IDk5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9TVFJJTkdfMTAwX0ZJRUxEX05VTUJFUiA9IDEwMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQzMl9VSU5UMzJfMTAxX0ZJRUxEX05VTUJFUiA9IDEwMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVEMzJfVUlOVDY0XzEwMl9GSUVMRF9OVU1CRVIgPSAxMDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQ2NF8xMDIgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9CT09MXzEwM19GSUVMRF9OVU1CRVIgPSAxMDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9CWVRFU18xMDRfRklFTERfTlVNQkVSID0gMTA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9ET1VCTEVfMTA1X0ZJRUxEX05VTUJFUiA9IDEwNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfRU5VTV8xMDZfRklFTERfTlVNQkVSID0gMTA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5aRVJPLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfRklYRUQzMl8xMDdfRklFTERfTlVNQkVSID0gMTA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVIgPSAxMDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9GTE9BVF8xMDlfRklFTERfTlVNQkVSID0gMTA5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X0lOVDMyXzExMF9GSUVMRF9OVU1CRVIgPSAxMTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQzMl8xMTAgPSAxMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExME9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUiA9IDExMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfTUVTU0FHRV8xMTJfRklFTERfTlVNQkVSID0gMTEyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0ZJWEVENjRfU0ZJWEVEMzJfMTEzX0ZJRUxEX05VTUJFUiA9IDExMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQzMl8xMTMgPSAxMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9TRklYRUQ2NF8xMTRfRklFTERfTlVNQkVSID0gMTE0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UMzJfMTE1X0ZJRUxEX05VTUJFUiA9IDExNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NJTlQ2NF8xMTZfRklFTERfTlVNQkVSID0gMTE2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1NUUklOR18xMTdfRklFTERfTlVNQkVSID0gMTE3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UMzJfMTE4X0ZJRUxEX05VTUJFUiA9IDExODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NGSVhFRDY0X1VJTlQ2NF8xMTlfRklFTERfTlVNQkVSID0gMTE5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkgewogICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9CT09MXzEyMF9GSUVMRF9OVU1CRVIgPSAxMjA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkJvb2wxMjBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJvb2wxMjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQzMl9ib29sXzEyMCA9IDEyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVIgPSAxMjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJCeXRlczEyMV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJCeXRlczEyMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRE9VQkxFXzEyMl9GSUVMRF9OVU1CRVIgPSAxMjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRG91YmxlMTIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRU5VTV8xMjNfRklFTERfTlVNQkVSID0gMTIzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJFbnVtMTIzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRW51bTEyMygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRklYRUQzMl8xMjRfRklFTERfTlVNQkVSID0gMTI0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0ZJWEVENjRfMTI1X0ZJRUxEX05VTUJFUiA9IDEyNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfRkxPQVRfMTI2X0ZJRUxEX05VTUJFUiA9IDEyNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGbG9hdDEyNkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX0lOVDMyXzEyN19GSUVMRF9OVU1CRVIgPSAxMjc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJJbnQzMjEyN187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQzMjEyN187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMySW50MzIxMjdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQzMl9JTlQ2NF8xMjhfRklFTERfTlVNQkVSID0gMTI4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkludDY0MTI4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDY0MTI4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMySW50NjQxMjgoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50NjRfMTI4ID0gMTI4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUiA9IDEyOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVEMzJfMTMwX0ZJRUxEX05VTUJFUiA9IDEzMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NGSVhFRDY0XzEzMV9GSUVMRF9OVU1CRVIgPSAxMzE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDY0XzEzMSA9IDEzMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU0lOVDMyXzEzMl9GSUVMRF9OVU1CRVIgPSAxMzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1NJTlQ2NF8xMzNfRklFTERfTlVNQkVSID0gMTMzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfU1RSSU5HXzEzNF9GSUVMRF9OVU1CRVIgPSAxMzQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlN0cmluZzEzNERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UMzJfVUlOVDMyXzEzNV9GSUVMRF9OVU1CRVIgPSAxMzU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDMyX1VJTlQ2NF8xMzZfRklFTERfTlVNQkVSID0gMTM2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDY0MTM2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfQk9PTF8xMzdfRklFTERfTlVNQkVSID0gMTM3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRCb29sMTM3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJvb2wxMzdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTaW50NjRCb29sMTM3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50NjRCb29sMTM3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfQllURVNfMTM4X0ZJRUxEX05VTUJFUiA9IDEzODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCeXRlczEzOF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfRE9VQkxFXzEzOV9GSUVMRF9OVU1CRVIgPSAxMzk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjREb3VibGUxMzlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0VOVU1fMTQwX0ZJRUxEX05VTUJFUiA9IDE0MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRFbnVtMTQwKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUiA9IDE0MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQzMl8xNDEgPSAxNDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfRklYRUQ2NF8xNDJfRklFTERfTlVNQkVSID0gMTQyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfRkxPQVRfMTQzX0ZJRUxEX05VTUJFUiA9IDE0MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M09yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSID0gMTQ0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQzMjE0NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50MzIxNDQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X0lOVDY0XzE0NV9GSUVMRF9OVU1CRVIgPSAxNDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X01FU1NBR0VfMTQ2X0ZJRUxEX05VTUJFUiA9IDE0NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDMyXzE0N19GSUVMRF9OVU1CRVIgPSAxNDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU0ZJWEVENjRfMTQ4X0ZJRUxEX05VTUJFUiA9IDE0ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfU0lOVDMyXzE0OV9GSUVMRF9OVU1CRVIgPSAxNDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9TSU5UNjRfMTUwX0ZJRUxEX05VTUJFUiA9IDE1MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9TVFJJTkdfMTUxX0ZJRUxEX05VTUJFUiA9IDE1MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TSU5UNjRfVUlOVDMyXzE1Ml9GSUVMRF9OVU1CRVIgPSAxNTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0VWludDMyMTUyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NJTlQ2NF9VSU5UNjRfMTUzX0ZJRUxEX05VTUJFUiA9IDE1MzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0VWludDY0MTUzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19CT09MXzE1NF9GSUVMRF9OVU1CRVIgPSAxNTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfQllURVNfMTU1X0ZJRUxEX05VTUJFUiA9IDE1NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0RPVUJMRV8xNTZfRklFTERfTlVNQkVSID0gMTU2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRU5VTV8xNTdfRklFTERfTlVNQkVSID0gMTU3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRklYRUQzMl8xNThfRklFTERfTlVNQkVSID0gMTU4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfRklYRUQ2NF8xNTlfRklFTERfTlVNQkVSID0gMTU5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0ZMT0FUXzE2MF9GSUVMRF9OVU1CRVIgPSAxNjA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0lOVDMyXzE2MV9GSUVMRF9OVU1CRVIgPSAxNjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX0lOVDY0XzE2Ml9GSUVMRF9OVU1CRVIgPSAxNjI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19NRVNTQUdFXzE2M19GSUVMRF9OVU1CRVIgPSAxNjM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVEMzJfMTY0X0ZJRUxEX05VTUJFUiA9IDE2NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVENjRfMTY1X0ZJRUxEX05VTUJFUiA9IDE2NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NJTlQzMl8xNjZfRklFTERfTlVNQkVSID0gMTY2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1NJTlQ2NF8xNjdfRklFTERfTlVNQkVSID0gMTY3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1NUUklOR19TVFJJTkdfMTY4X0ZJRUxEX05VTUJFUiA9IDE2ODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1VJTlQzMl8xNjlfRklFTERfTlVNQkVSID0gMTY5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfU1RSSU5HX1VJTlQ2NF8xNzBfRklFTERfTlVNQkVSID0gMTcwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9CT09MXzE3MV9GSUVMRF9OVU1CRVIgPSAxNzE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJvb2wxNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVIgPSAxNzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJCeXRlczE3Ml87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRE9VQkxFXzE3M19GSUVMRF9OVU1CRVIgPSAxNzM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkRPVUJMRSwKICAgICAgICAgICAgICAgICAgMEQpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwVWludDMyRG91YmxlMTczXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRG91YmxlMTczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRG91YmxlMTczXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRG91YmxlMTczTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRU5VTV8xNzRfRklFTERfTlVNQkVSID0gMTc0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJFbnVtMTc0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJFbnVtMTc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRW51bTE3NF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRklYRUQzMl8xNzVfRklFTERfTlVNQkVSID0gMTc1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0ZJWEVENjRfMTc2X0ZJRUxEX05VTUJFUiA9IDE3NjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDY0XzE3NiA9IDE3Njs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfRkxPQVRfMTc3X0ZJRUxEX05VTUJFUiA9IDE3NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBVaW50MzJGbG9hdDE3N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX0lOVDMyXzE3OF9GSUVMRF9OVU1CRVIgPSAxNzg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMkludDMyMTc4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJJbnQzMjE3OF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQzMjE3OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQzMjE3OF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQzMl9JTlQ2NF8xNzlfRklFTERfTlVNQkVSID0gMTc5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDY0MTc5XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQ2NDE3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMySW50NjQxNzlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQ2NF8xNzkgPSAxNzk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUiA9IDE4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVEMzJfMTgxX0ZJRUxEX05VTUJFUiA9IDE4MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NGSVhFRDY0XzE4Ml9GSUVMRF9OVU1CRVIgPSAxODI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkNjRfMTgyID0gMTgyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU0lOVDMyXzE4M19GSUVMRF9OVU1CRVIgPSAxODM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1NJTlQ2NF8xODRfRklFTERfTlVNQkVSID0gMTg0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDY0MTg0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ludDY0MTg0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfU1RSSU5HXzE4NV9GSUVMRF9OVU1CRVIgPSAxODU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UMzJfVUlOVDMyXzE4Nl9GSUVMRF9OVU1CRVIgPSAxODY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50MzJVaW50MzIxODZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyVWludDMyMTg2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDMyX1VJTlQ2NF8xODdfRklFTERfTlVNQkVSID0gMTg3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJVaW50NjQxODdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyVWludDY0MTg3KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfQk9PTF8xODhfRklFTERfTlVNQkVSID0gMTg4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJvb2wxODhFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50NjRCb29sMTg4XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qm9vbDE4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODhPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfQllURVNfMTg5X0ZJRUxEX05VTUJFUiA9IDE4OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRCeXRlczE4OV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OSA9IDE4OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfRE9VQkxFXzE5MF9GSUVMRF9OVU1CRVIgPSAxOTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RG91YmxlMTkwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5ET1VCTEUsCiAgICAgICAgICAgICAgICAgIDBEKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjREb3VibGUxOTBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDY0X2RvdWJsZV8xOTAgPSAxOTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0VOVU1fMTkxX0ZJRUxEX05VTUJFUiA9IDE5MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0RW51bTE5MURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uWkVSTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUiA9IDE5MjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDMyXzE5MiA9IDE5Mjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfRklYRUQ2NF8xOTNfRklFTERfTlVNQkVSID0gMTkzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfRkxPQVRfMTk0X0ZJRUxEX05VTUJFUiA9IDE5NDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0RmxvYXQxOTREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRkxPQVQsCiAgICAgICAgICAgICAgICAgIDBGKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSID0gMTk1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NEludDMyMTk1XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEludDMyMTk1XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDMyMTk1XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0SW50MzIxOTUoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X0lOVDY0XzE5Nl9GSUVMRF9OVU1CRVIgPSAxOTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEludDY0MTk2XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQ2NDE5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X01FU1NBR0VfMTk3X0ZJRUxEX05VTUJFUiA9IDE5NzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDMyXzE5OF9GSUVMRF9OVU1CRVIgPSAxOTg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU0ZJWEVENjRfMTk5X0ZJRUxEX05VTUJFUiA9IDE5OTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpIHsKICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgfQogICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfU0lOVDMyXzIwMF9GSUVMRF9OVU1CRVIgPSAyMDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ludDMyMjAwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9TSU5UNjRfMjAxX0ZJRUxEX05VTUJFUiA9IDIwMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U2ludDY0MjAxRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ludDY0MjAxXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9TVFJJTkdfMjAyX0ZJRUxEX05VTUJFUiA9IDIwMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyT3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BUF9VSU5UNjRfVUlOVDMyXzIwM19GSUVMRF9OVU1CRVIgPSAyMDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFQX1VJTlQ2NF9VSU5UNjRfMjA0X0ZJRUxEX05VTUJFUiA9IDIwNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50NjQyMDQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xFbnVtNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLAogICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkNjQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLAogICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50MzI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLAogICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLAogICAgICAgICAgRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLAogICAgICAgICAgRmllbGRNYXBCb29sU2ludDMyMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50NjQxNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSwKICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplQm9vbGVhbk1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLAogICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCksCiAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJFbnVtMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDM3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEVudW0zOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMzkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGbG9hdDQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCksCiAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSwKICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLAogICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDU5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLAogICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJNZXNzYWdlNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ZpeGVkMzI2MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyU2ludDY0NjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLAogICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDY2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKSwKICAgICAgICAgIEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCksCiAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNjkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRFbnVtNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQzMjc2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRTaW50MzI4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCksCiAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLAogICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSwKICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCksCiAgICAgICAgICBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgODkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTAwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTE3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCksCiAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLAogICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTI2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTMzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJTdHJpbmcxMzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLAogICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMzcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTM5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLAogICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0SW50NjQxNDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTQ3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCksCiAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDMyMTUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSwKICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRW51bTE1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNTcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTU4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2MSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdTaW50NjQxNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTY3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCksCiAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNjgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSwKICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE2OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLAogICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyQnl0ZXMxNzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTczKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZsb2F0MTc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE3Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLAogICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNzgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTc5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxODApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Mik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ludDY0MTg0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4NSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4Nyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTg4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE4OSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0RG91YmxlMTkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5MCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEVudW0xOTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Myk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRGbG9hdDE5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKSwKICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5Nik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTk3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE5OCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLAogICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxOTkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCksCiAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBmaWVsZE1hcEJvb2xCb29sMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXyA9IEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZmllbGRNYXBCb29sQnl0ZXMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfXyA9IEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGZpZWxkTWFwQm9vbERvdWJsZTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sRW51bTRfXyA9IEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBmaWVsZE1hcEJvb2xFbnVtNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fID0gRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18gPSBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgZmllbGRNYXBCb29sRml4ZWQ2NDZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3X18gPSBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGZpZWxkTWFwQm9vbEZsb2F0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sSW50MzI4X18gPSBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIGZpZWxkTWFwQm9vbEludDMyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18gPSBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGZpZWxkTWFwQm9vbEludDY0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfXyA9IEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXyA9IEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExLCBmaWVsZE1hcEJvb2xTZml4ZWQzMjExX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fID0gRmllbGRNYXBCb29sU2ZpeGVkNjQxMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIsIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBCb29sU2ludDMyMTNfXyA9IEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMywgZmllbGRNYXBCb29sU2ludDMyMTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBCb29sU2ludDY0MTRfXyA9IEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNCwgZmllbGRNYXBCb29sU2ludDY0MTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1X18gPSBGaWVsZE1hcEJvb2xTdHJpbmcxNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUsIGZpZWxkTWFwQm9vbFN0cmluZzE1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18gPSBGaWVsZE1hcEJvb2xVaW50MzIxNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTYsIGZpZWxkTWFwQm9vbFVpbnQzMjE2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18gPSBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcsIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfXyA9IEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fID0gRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTksIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18gPSBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAsIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXyA9IEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjEsIGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyX18gPSBGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIyLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM19fID0gRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMywgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18gPSBGaWVsZE1hcEZpeGVkMzJGbG9hdDI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNCwgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXyA9IEZpZWxkTWFwRml4ZWQzMkludDMyMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI1LCBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fID0gRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjYsIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18gPSBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI3LCBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4X18gPSBGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyOCwgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfXyA9IEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI5LCBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18gPSBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMzAsIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18gPSBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMzEsIGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fID0gRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMyLCBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fID0gRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMzLCBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fID0gRmllbGRNYXBGaXhlZDMyVWludDY0MzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM0LCBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18gPSBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM1LCBmaWVsZE1hcEZpeGVkNjRCb29sMzVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfXyA9IEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM2LCBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fID0gRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM3LCBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4X18gPSBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM4LCBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV9fID0gRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzOSwgZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXyA9IEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDAsIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV9fID0gRmllbGRNYXBGaXhlZDY0RmxvYXQ0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDEsIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyX18gPSBGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0MiwgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfXyA9IEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQzLCBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fID0gRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NCwgZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fID0gRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDUsIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18gPSBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0NiwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fID0gRmllbGRNYXBGaXhlZDY0U2ludDMyNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ3LCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fID0gRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ4LCBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyA9IEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MCwgZmllbGRNYXBGaXhlZDY0VWludDMyNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MSwgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEludDMyQm9vbDUyX18gPSBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MiwgZmllbGRNYXBJbnQzMkJvb2w1Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTMsIGZpZWxkTWFwSW50MzJCeXRlczUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18gPSBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU0LCBmaWVsZE1hcEludDMyRG91YmxlNTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyRW51bTU1X18gPSBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1NSwgZmllbGRNYXBJbnQzMkVudW01NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXyA9IEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU2LCBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fID0gRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTcsIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF9fID0gRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU4LCBmaWVsZE1hcEludDMyRmxvYXQ1OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fID0gRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU5LCBmaWVsZE1hcEludDMySW50MzI1OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF9fID0gRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYwLCBmaWVsZE1hcEludDMySW50NjQ2MF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fID0gRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjEsIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXyA9IEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MiwgZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXyA9IEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2MywgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fID0gRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NCwgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDMyU2ludDY0NjVfXyA9IEZpZWxkTWFwSW50MzJTaW50NjQ2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjUsIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl9fID0gRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2NiwgZmllbGRNYXBJbnQzMlN0cmluZzY2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfXyA9IEZpZWxkTWFwSW50MzJVaW50MzI2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNjcsIGZpZWxkTWFwSW50MzJVaW50MzI2N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18gPSBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDY4LCBmaWVsZE1hcEludDMyVWludDY0NjhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5X18gPSBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2OSwgZmllbGRNYXBJbnQ2NEJvb2w2OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50NjRCeXRlczcwX18gPSBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzAsIGZpZWxkTWFwSW50NjRCeXRlczcwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18gPSBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcxLCBmaWVsZE1hcEludDY0RG91YmxlNzFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyX18gPSBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3MiwgZmllbGRNYXBJbnQ2NEVudW03Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXyA9IEZpZWxkTWFwSW50NjRGaXhlZDMyNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDczLCBmaWVsZE1hcEludDY0Rml4ZWQzMjczX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fID0gRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzQsIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcEludDY0RmxvYXQ3NV9fID0gRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc1LCBmaWVsZE1hcEludDY0RmxvYXQ3NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl9fID0gRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc2LCBmaWVsZE1hcEludDY0SW50MzI3Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N19fID0gRmllbGRNYXBJbnQ2NEludDY0NzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDc3LCBmaWVsZE1hcEludDY0SW50NjQ3N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF9fID0gRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNzgsIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXyA9IEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3OSwgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfXyA9IEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4MCwgZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwSW50NjRTaW50MzI4MV9fID0gRmllbGRNYXBJbnQ2NFNpbnQzMjgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4MSwgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfXyA9IEZpZWxkTWFwSW50NjRTaW50NjQ4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODIsIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fID0gRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4MywgZmllbGRNYXBJbnQ2NFN0cmluZzgzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfXyA9IEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODQsIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBJbnQ2NFVpbnQ2NDg1X18gPSBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg1LCBmaWVsZE1hcEludDY0VWludDY0ODVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2X18gPSBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4NiwgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18gPSBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoODcsIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4X18gPSBGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDg4LCBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRW51bTg5X18gPSBGaWVsZE1hcFNmaXhlZDMyRW51bTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4OSwgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfXyA9IEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkwLCBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV9fID0gRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTEsIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fID0gRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkyLCBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fID0gRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDkzLCBmaWVsZE1hcFNmaXhlZDMySW50MzI5M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fID0gRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDk0LCBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fID0gRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTUsIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NiwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5NywgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fID0gRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5OCwgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOTksIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18gPSBGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDAsIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDEsIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDIsIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXyA9IEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDMsIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fID0gRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDQsIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDUsIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXyA9IEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDYsIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18gPSBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTA3LCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fID0gRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOCwgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18gPSBGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwOSwgZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyA9IEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEwLCBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fID0gRmllbGRNYXBTZml4ZWQ2NEludDY0MTExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTEsIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyX18gPSBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEyLCBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18gPSBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExMywgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXyA9IEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE0LCBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1X18gPSBGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTUsIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2X18gPSBGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTYsIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN19fID0gRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE3LCBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF9fID0gRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE4LCBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV9fID0gRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE5LCBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXyA9IEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIwLCBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfXyA9IEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyMSwgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXyA9IEZpZWxkTWFwU2ludDMyRG91YmxlMTIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjIsIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXyA9IEZpZWxkTWFwU2ludDMyRW51bTEyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTIzLCBmaWVsZE1hcFNpbnQzMkVudW0xMjNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fID0gRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjQsIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18gPSBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyNSwgZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2X18gPSBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjYsIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMkludDMyMTI3X18gPSBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjcsIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMkludDY0MTI4X18gPSBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMjgsIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5X18gPSBGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyOSwgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fID0gRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMwLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fID0gRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMxLCBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyX18gPSBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMyLCBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM19fID0gRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzMywgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDMyU3RyaW5nMTM0X18gPSBGaWVsZE1hcFNpbnQzMlN0cmluZzEzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM0LCBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fID0gRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzNSwgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50MzJVaW50NjQxMzZfXyA9IEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzYsIGZpZWxkTWFwU2ludDMyVWludDY0MTM2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyA9IEZpZWxkTWFwU2ludDY0Qm9vbDEzN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTM3LCBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXyA9IEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzOCwgZmllbGRNYXBTaW50NjRCeXRlczEzOF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTaW50NjREb3VibGUxMzlfXyA9IEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMzksIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXyA9IEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQwLCBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fID0gRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDEsIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18gPSBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0MiwgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18gPSBGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDMsIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18gPSBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDQsIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18gPSBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNDUsIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18gPSBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0NiwgZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fID0gRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ3LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fID0gRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ4LCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5X18gPSBGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQ5LCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fID0gRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MCwgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18gPSBGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUxLCBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1MiwgZmllbGRNYXBTaW50NjRVaW50MzIxNTJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfXyA9IEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTMsIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18gPSBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NCwgZmllbGRNYXBTdHJpbmdCb29sMTU0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTU1LCBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfXyA9IEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNTYsIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18gPSBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1NywgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OCwgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18gPSBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE1OSwgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fID0gRmllbGRNYXBTdHJpbmdGbG9hdDE2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTYwLCBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXyA9IEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2MSwgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18gPSBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjIsIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fID0gRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjMsIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0X18gPSBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjQsIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV9fID0gRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY1LCBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl9fID0gRmllbGRNYXBTdHJpbmdTaW50MzIxNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2NiwgZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3X18gPSBGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY3LCBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18gPSBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTY4LCBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXyA9IEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNjksIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fID0gRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3MCwgZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fID0gRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzEsIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJCeXRlczE3Ml9fID0gRmllbGRNYXBVaW50MzJCeXRlczE3MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcyLCBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fID0gRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3MywgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF9fID0gRmllbGRNYXBVaW50MzJFbnVtMTc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNzQsIGZpZWxkTWFwVWludDMyRW51bTE3NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18gPSBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3NSwgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXyA9IEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTc2LCBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfXyA9IEZpZWxkTWFwVWludDMyRmxvYXQxNzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3NywgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfXyA9IEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3OCwgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDMySW50NjQxNzlfXyA9IEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3OSwgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXyA9IEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgwLCBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18gPSBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODEsIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18gPSBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODIsIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50MzJTaW50MzIxODNfXyA9IEZpZWxkTWFwVWludDMyU2ludDMyMTgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODMsIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18gPSBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg0LCBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXyA9IEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODUsIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2X18gPSBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg2LCBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N19fID0gRmllbGRNYXBVaW50MzJVaW50NjQxODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4NywgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGZpZWxkTWFwVWludDY0Qm9vbDE4OF9fID0gRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxODgsIGZpZWxkTWFwVWludDY0Qm9vbDE4OF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fID0gRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTg5LCBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF9fID0gRmllbGRNYXBVaW50NjREb3VibGUxOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5MCwgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV9fID0gRmllbGRNYXBVaW50NjRFbnVtMTkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTEsIGZpZWxkTWFwVWludDY0RW51bTE5MV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18gPSBGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5MiwgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXyA9IEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTkzLCBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXyA9IEZpZWxkTWFwVWludDY0RmxvYXQxOTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5NCwgZmllbGRNYXBVaW50NjRGbG9hdDE5NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXyA9IEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5NSwgZmllbGRNYXBVaW50NjRJbnQzMjE5NV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXyA9IEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5NiwgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyA9IEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTk3LCBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTgsIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18gPSBGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOTksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXyA9IEZpZWxkTWFwVWludDY0U2ludDMyMjAwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDAsIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAxLCBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDIsIGZpZWxkTWFwVWludDY0U3RyaW5nMjAyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGZpZWxkTWFwVWludDY0VWludDMyMjAzX18gPSBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAzLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fID0gRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNCwgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQk9PTF8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfQllURVNfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRE9VQkxFXzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRG91YmxlMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfRU5VTV80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9GSVhFRDMyXzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZJWEVENjRfNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX0ZMT0FUXzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfSU5UMzJfOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9JTlQ2NF85X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX01FU1NBR0VfMTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NGSVhFRDMyXzExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0ZJWEVENjRfMTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfU0lOVDMyXzEzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9TSU5UNjRfMTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9CT09MX1NUUklOR18xNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0JPT0xfVUlOVDMyXzE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfQk9PTF9VSU5UNjRfMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CT09MXzE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9CWVRFU18xOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9ET1VCTEVfMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9FTlVNXzIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0ZJWEVEMzJfMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRklYRUQ2NF8yM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfRkxPQVRfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9JTlQzMl8yNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX0lOVDY0XzI2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9NRVNTQUdFXzI3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TRklYRUQzMl8yOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NGSVhFRDY0XzI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1NJTlQzMl8zMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfU0lOVDY0XzMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQzMl9TVFJJTkdfMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDMyX1VJTlQzMl8zM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVEMzJfVUlOVDY0XzM0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQk9PTF8zNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfQllURVNfMzZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRE9VQkxFXzM3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfRU5VTV8zOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9GSVhFRDMyXzM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZJWEVENjRfNDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X0ZMT0FUXzQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfSU5UMzJfNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9JTlQ2NF80M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfTUVTU0FHRV80NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU0ZJWEVEMzJfNDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TRklYRUQ2NF80Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9TSU5UMzJfNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1NJTlQ2NF80OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0ZJWEVENjRfU1RSSU5HXzQ5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfRklYRUQ2NF9VSU5UMzJfNTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9GSVhFRDY0X1VJTlQ2NF81MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQk9PTF81Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfQllURVNfNTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRE9VQkxFXzU0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfRU5VTV81NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9GSVhFRDMyXzU2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZJWEVENjRfNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX0ZMT0FUXzU4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfSU5UMzJfNTlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9JTlQ2NF82MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfTUVTU0FHRV82MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU0ZJWEVEMzJfNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TRklYRUQ2NF82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9TSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1NJTlQ2NF82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UMzJfU1RSSU5HXzY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQzMl9VSU5UMzJfNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDMyX1VJTlQ2NF82OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JPT0xfNjlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0JZVEVTXzcwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0RPVUJMRV83MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0VOVU1fNzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfRklYRUQzMl83M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GSVhFRDY0Xzc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9GTE9BVF83NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X0lOVDMyXzc2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfSU5UNjRfNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X01FU1NBR0VfNzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NGSVhFRDMyXzc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0ZJWEVENjRfODBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfU0lOVDMyXzgxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9TSU5UNjRfODJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX0lOVDY0X1NUUklOR184M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfSU5UNjRfVUlOVDMyXzg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9JTlQ2NF9VSU5UNjRfODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CT09MXzg2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9CWVRFU184N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9ET1VCTEVfODhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9FTlVNXzg5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0ZJWEVEMzJfOTBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRklYRUQ2NF85MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfRkxPQVRfOTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9JTlQzMl85M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX0lOVDY0Xzk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9NRVNTQUdFXzk1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9TRklYRUQzMl85Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NGSVhFRDY0Xzk3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1NJTlQzMl85OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU0lOVDY0Xzk5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVEMzJfU1RSSU5HXzEwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQzMl9VSU5UMzJfMTAxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDMyX1VJTlQ2NF8xMDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JPT0xfMTAzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0JZVEVTXzEwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0RPVUJMRV8xMDVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0VOVU1fMTA2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfRklYRUQzMl8xMDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GSVhFRDY0XzEwOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9GTE9BVF8xMDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X0lOVDMyXzExMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfSU5UNjRfMTExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X01FU1NBR0VfMTEyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NGSVhFRDMyXzExM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0ZJWEVENjRfMTE0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfU0lOVDMyXzExNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9TSU5UNjRfMTE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NGSVhFRDY0X1NUUklOR18xMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0ZJWEVENjRfVUlOVDMyXzExOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TRklYRUQ2NF9VSU5UNjRfMTE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JPT0xfMTIwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0JZVEVTXzEyMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0RPVUJMRV8xMjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0VOVU1fMTIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfRklYRUQzMl8xMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GSVhFRDY0XzEyNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9GTE9BVF8xMjZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX0lOVDMyXzEyN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfSU5UNjRfMTI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX01FU1NBR0VfMTI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NGSVhFRDMyXzEzMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0ZJWEVENjRfMTMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfU0lOVDMyXzEzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9TSU5UNjRfMTMzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDMyX1NUUklOR18xMzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UMzJfVUlOVDMyXzEzNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQzMl9VSU5UNjRfMTM2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CT09MXzEzN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9CWVRFU18xMzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9ET1VCTEVfMTM5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9FTlVNXzE0MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0ZJWEVEMzJfMTQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRklYRUQ2NF8xNDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfRkxPQVRfMTQzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9JTlQzMl8xNDRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X0lOVDY0XzE0NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9NRVNTQUdFXzE0Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TRklYRUQzMl8xNDdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NGSVhFRDY0XzE0OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1NJTlQzMl8xNDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfU0lOVDY0XzE1MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NJTlQ2NF9TVFJJTkdfMTUxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU0lOVDY0X1VJTlQzMl8xNTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TSU5UNjRfVUlOVDY0XzE1M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQk9PTF8xNTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfQllURVNfMTU1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRE9VQkxFXzE1Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfRU5VTV8xNTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19GSVhFRDMyXzE1OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZJWEVENjRfMTU5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX0ZMT0FUXzE2MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfSU5UMzJfMTYxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19JTlQ2NF8xNjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfTUVTU0FHRV8xNjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU0ZJWEVEMzJfMTY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TRklYRUQ2NF8xNjVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19TSU5UMzJfMTY2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1NJTlQ2NF8xNjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9TVFJJTkdfU1RSSU5HXzE2OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1NUUklOR19VSU5UMzJfMTY5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfU1RSSU5HX1VJTlQ2NF8xNzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JPT0xfMTcxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0JZVEVTXzE3Ml9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0RPVUJMRV8xNzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0VOVU1fMTc0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfRklYRUQzMl8xNzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GSVhFRDY0XzE3Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9GTE9BVF8xNzdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX0lOVDMyXzE3OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfSU5UNjRfMTc5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX01FU1NBR0VfMTgwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NGSVhFRDMyXzE4MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0ZJWEVENjRfMTgyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfU0lOVDMyXzE4M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9TSU5UNjRfMTg0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDMyX1NUUklOR18xODVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UMzJfVUlOVDMyXzE4Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQzMl9VSU5UNjRfMTg3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CT09MXzE4OF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9CWVRFU18xODlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9ET1VCTEVfMTkwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9FTlVNXzE5MV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0ZJWEVEMzJfMTkyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRklYRUQ2NF8xOTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfRkxPQVRfMTk0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9JTlQzMl8xOTVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X0lOVDY0XzE5Nl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9NRVNTQUdFXzE5N19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TRklYRUQzMl8xOThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NGSVhFRDY0XzE5OV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1NJTlQzMl8yMDBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfU0lOVDY0XzIwMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFQX1VJTlQ2NF9TVFJJTkdfMjAyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9NQVBfVUlOVDY0X1VJTlQzMl8yMDNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BUF9VSU5UNjRfVUlOVDY0XzIwNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcykKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpOwogICAgICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCk7CiAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgICAgICAgIGNhc2UgMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCk7CiAgICAgICAgICBjYXNlIDE4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKTsKICAgICAgICAgIGNhc2UgMTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgICAgICAgIGNhc2UgMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCk7CiAgICAgICAgICBjYXNlIDIxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKTsKICAgICAgICAgIGNhc2UgMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgICAgICAgY2FzZSAyMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCk7CiAgICAgICAgICBjYXNlIDI0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCk7CiAgICAgICAgICBjYXNlIDI1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCk7CiAgICAgICAgICBjYXNlIDI2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCk7CiAgICAgICAgICBjYXNlIDI3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKTsKICAgICAgICAgIGNhc2UgMjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgICAgICAgIGNhc2UgMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKTsKICAgICAgICAgIGNhc2UgMzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCk7CiAgICAgICAgICBjYXNlIDMxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpOwogICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKTsKICAgICAgICAgIGNhc2UgMzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCk7CiAgICAgICAgICBjYXNlIDM0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpOwogICAgICAgICAgY2FzZSAzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCk7CiAgICAgICAgICBjYXNlIDM2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICBjYXNlIDM3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpOwogICAgICAgICAgY2FzZSAzODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCk7CiAgICAgICAgICBjYXNlIDM5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKTsKICAgICAgICAgIGNhc2UgNDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgY2FzZSA0MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpOwogICAgICAgICAgY2FzZSA0MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpOwogICAgICAgICAgY2FzZSA0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgICAgICAgY2FzZSA0NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCk7CiAgICAgICAgICBjYXNlIDQ1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICBjYXNlIDQ2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpOwogICAgICAgICAgY2FzZSA0ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIGNhc2UgNDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAgICAgICBjYXNlIDUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpOwogICAgICAgICAgY2FzZSA1MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIGNhc2UgNTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgICAgICAgIGNhc2UgNTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCk7CiAgICAgICAgICBjYXNlIDU0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKTsKICAgICAgICAgIGNhc2UgNTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKTsKICAgICAgICAgIGNhc2UgNTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKTsKICAgICAgICAgIGNhc2UgNTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKTsKICAgICAgICAgIGNhc2UgNTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAgICAgICBjYXNlIDU5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpOwogICAgICAgICAgY2FzZSA2MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIGNhc2UgNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKTsKICAgICAgICAgIGNhc2UgNjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCk7CiAgICAgICAgICBjYXNlIDYzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpOwogICAgICAgICAgY2FzZSA2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCk7CiAgICAgICAgICBjYXNlIDY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKTsKICAgICAgICAgIGNhc2UgNjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpOwogICAgICAgICAgY2FzZSA2NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICBjYXNlIDY4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKTsKICAgICAgICAgIGNhc2UgNjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKTsKICAgICAgICAgIGNhc2UgNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAgICAgICBjYXNlIDcxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKTsKICAgICAgICAgIGNhc2UgNzI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKTsKICAgICAgICAgIGNhc2UgNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKTsKICAgICAgICAgIGNhc2UgNzU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgICBjYXNlIDc2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgY2FzZSA3NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKTsKICAgICAgICAgIGNhc2UgNzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKTsKICAgICAgICAgIGNhc2UgNzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCk7CiAgICAgICAgICBjYXNlIDgwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpOwogICAgICAgICAgY2FzZSA4MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCk7CiAgICAgICAgICBjYXNlIDgyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgICAgICAgIGNhc2UgODM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpOwogICAgICAgICAgY2FzZSA4NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCk7CiAgICAgICAgICBjYXNlIDg1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKTsKICAgICAgICAgIGNhc2UgODY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKTsKICAgICAgICAgIGNhc2UgODc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgICBjYXNlIDg4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKTsKICAgICAgICAgIGNhc2UgODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKTsKICAgICAgICAgIGNhc2UgOTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKTsKICAgICAgICAgIGNhc2UgOTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIGNhc2UgOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCk7CiAgICAgICAgICBjYXNlIDkzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpOwogICAgICAgICAgY2FzZSA5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKTsKICAgICAgICAgIGNhc2UgOTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKTsKICAgICAgICAgIGNhc2UgOTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgICBjYXNlIDk3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpOwogICAgICAgICAgY2FzZSA5ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAgICAgICBjYXNlIDk5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKTsKICAgICAgICAgIGNhc2UgMTAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAgICAgICBjYXNlIDEwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpOwogICAgICAgICAgY2FzZSAxMDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICAgIGNhc2UgMTAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpOwogICAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpOwogICAgICAgICAgY2FzZSAxMDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICAgIGNhc2UgMTA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpOwogICAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCk7CiAgICAgICAgICBjYXNlIDEwODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKTsKICAgICAgICAgIGNhc2UgMTA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKTsKICAgICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKTsKICAgICAgICAgIGNhc2UgMTExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKTsKICAgICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpOwogICAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpOwogICAgICAgICAgY2FzZSAxMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpOwogICAgICAgICAgY2FzZSAxMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKTsKICAgICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCk7CiAgICAgICAgICBjYXNlIDExNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpOwogICAgICAgICAgY2FzZSAxMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKTsKICAgICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCk7CiAgICAgICAgICBjYXNlIDEyMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgICBjYXNlIDEyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCk7CiAgICAgICAgICBjYXNlIDEyMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgICBjYXNlIDEyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAgICAgICBjYXNlIDEyNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCk7CiAgICAgICAgICBjYXNlIDEyNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpOwogICAgICAgICAgY2FzZSAxMjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKTsKICAgICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCk7CiAgICAgICAgICBjYXNlIDEyOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCk7CiAgICAgICAgICBjYXNlIDEzMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKTsKICAgICAgICAgIGNhc2UgMTMyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpOwogICAgICAgICAgY2FzZSAxMzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCk7CiAgICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgICAgICAgIGNhc2UgMTM1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpOwogICAgICAgICAgY2FzZSAxMzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCk7CiAgICAgICAgICBjYXNlIDEzODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpOwogICAgICAgICAgY2FzZSAxMzk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCk7CiAgICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCk7CiAgICAgICAgICBjYXNlIDE0MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCk7CiAgICAgICAgICBjYXNlIDE0MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCk7CiAgICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpOwogICAgICAgICAgY2FzZSAxNDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKTsKICAgICAgICAgIGNhc2UgMTQ1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCk7CiAgICAgICAgICBjYXNlIDE0NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpOwogICAgICAgICAgY2FzZSAxNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKTsKICAgICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpOwogICAgICAgICAgY2FzZSAxNTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCk7CiAgICAgICAgICBjYXNlIDE1MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpOwogICAgICAgICAgY2FzZSAxNTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCk7CiAgICAgICAgICBjYXNlIDE1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCk7CiAgICAgICAgICBjYXNlIDE1NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpOwogICAgICAgICAgY2FzZSAxNTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCk7CiAgICAgICAgICBjYXNlIDE1NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCk7CiAgICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCk7CiAgICAgICAgICBjYXNlIDE1OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCk7CiAgICAgICAgICBjYXNlIDE2MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpOwogICAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKTsKICAgICAgICAgIGNhc2UgMTYyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCk7CiAgICAgICAgICBjYXNlIDE2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCk7CiAgICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpOwogICAgICAgICAgY2FzZSAxNjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKTsKICAgICAgICAgIGNhc2UgMTY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCk7CiAgICAgICAgICBjYXNlIDE2ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKTsKICAgICAgICAgIGNhc2UgMTY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCk7CiAgICAgICAgICBjYXNlIDE3MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCk7CiAgICAgICAgICBjYXNlIDE3MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCk7CiAgICAgICAgICBjYXNlIDE3NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCk7CiAgICAgICAgICBjYXNlIDE3NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCk7CiAgICAgICAgICBjYXNlIDE3NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgICAgY2FzZSAxNzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCk7CiAgICAgICAgICBjYXNlIDE4MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCk7CiAgICAgICAgICBjYXNlIDE4MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpOwogICAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKTsKICAgICAgICAgIGNhc2UgMTgzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpOwogICAgICAgICAgY2FzZSAxODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAgICAgICBjYXNlIDE4NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKTsKICAgICAgICAgIGNhc2UgMTg2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpOwogICAgICAgICAgY2FzZSAxODc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCk7CiAgICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCk7CiAgICAgICAgICBjYXNlIDE4OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgICAgY2FzZSAxOTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAgICAgICBjYXNlIDE5MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCk7CiAgICAgICAgICBjYXNlIDE5MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCk7CiAgICAgICAgICBjYXNlIDE5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpOwogICAgICAgICAgY2FzZSAxOTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICAgIGNhc2UgMTk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCk7CiAgICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCk7CiAgICAgICAgICBjYXNlIDE5ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpOwogICAgICAgICAgY2FzZSAxOTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgICAgICAgY2FzZSAyMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCk7CiAgICAgICAgICBjYXNlIDIwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKTsKICAgICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpOwogICAgICAgICAgY2FzZSAyMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDY0OSgpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpOwogICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICAgIGNhc2UgMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCk7CiAgICAgICAgICBjYXNlIDEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCk7CiAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKTsKICAgICAgICAgIGNhc2UgMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgICAgY2FzZSAxODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpOwogICAgICAgICAgY2FzZSAxOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgICAgICAgIGNhc2UgMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgICAgY2FzZSAyMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpOwogICAgICAgICAgY2FzZSAyMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpOwogICAgICAgICAgY2FzZSAyMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpOwogICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKTsKICAgICAgICAgIGNhc2UgMjU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCk7CiAgICAgICAgICBjYXNlIDI2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpOwogICAgICAgICAgY2FzZSAyNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpOwogICAgICAgICAgY2FzZSAyODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgICAgICAgIGNhc2UgMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCk7CiAgICAgICAgICBjYXNlIDMwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKTsKICAgICAgICAgIGNhc2UgMzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpOwogICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCk7CiAgICAgICAgICBjYXNlIDMzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgICAgICAgIGNhc2UgMzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpOwogICAgICAgICAgY2FzZSAzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgY2FzZSAzNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKTsKICAgICAgICAgIGNhc2UgMzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpOwogICAgICAgICAgY2FzZSAzODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgY2FzZSAzOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgICAgICAgY2FzZSA0MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgY2FzZSA0MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKTsKICAgICAgICAgIGNhc2UgNDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAgICAgICBjYXNlIDQzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpOwogICAgICAgICAgY2FzZSA0NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpOwogICAgICAgICAgY2FzZSA0NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKTsKICAgICAgICAgIGNhc2UgNDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICBjYXNlIDQ3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIGNhc2UgNDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpOwogICAgICAgICAgY2FzZSA0OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCk7CiAgICAgICAgICBjYXNlIDUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIGNhc2UgNTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpOwogICAgICAgICAgY2FzZSA1MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKTsKICAgICAgICAgIGNhc2UgNTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpOwogICAgICAgICAgY2FzZSA1NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgICAgICAgY2FzZSA1NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKTsKICAgICAgICAgIGNhc2UgNTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICBjYXNlIDU3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpOwogICAgICAgICAgY2FzZSA1ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCk7CiAgICAgICAgICBjYXNlIDU5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIGNhc2UgNjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpOwogICAgICAgICAgY2FzZSA2MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKTsKICAgICAgICAgIGNhc2UgNjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpOwogICAgICAgICAgY2FzZSA2MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCk7CiAgICAgICAgICBjYXNlIDY0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCk7CiAgICAgICAgICBjYXNlIDY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCk7CiAgICAgICAgICBjYXNlIDY2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCk7CiAgICAgICAgICBjYXNlIDY3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCk7CiAgICAgICAgICBjYXNlIDY4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCk7CiAgICAgICAgICBjYXNlIDY5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpOwogICAgICAgICAgY2FzZSA3MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAgICAgICBjYXNlIDcxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCk7CiAgICAgICAgICBjYXNlIDcyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgICAgICAgY2FzZSA3MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKTsKICAgICAgICAgIGNhc2UgNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCk7CiAgICAgICAgICBjYXNlIDc1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKTsKICAgICAgICAgIGNhc2UgNzY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpOwogICAgICAgICAgY2FzZSA3NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgICBjYXNlIDc4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpOwogICAgICAgICAgY2FzZSA3OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCk7CiAgICAgICAgICBjYXNlIDgwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKTsKICAgICAgICAgIGNhc2UgODE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKTsKICAgICAgICAgIGNhc2UgODI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgICAgICAgIGNhc2UgODM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICAgIGNhc2UgODQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKTsKICAgICAgICAgIGNhc2UgODU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKTsKICAgICAgICAgIGNhc2UgODY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCk7CiAgICAgICAgICBjYXNlIDg3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKTsKICAgICAgICAgIGNhc2UgODg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKTsKICAgICAgICAgIGNhc2UgODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCk7CiAgICAgICAgICBjYXNlIDkwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpOwogICAgICAgICAgY2FzZSA5MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKTsKICAgICAgICAgIGNhc2UgOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpOwogICAgICAgICAgY2FzZSA5MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCk7CiAgICAgICAgICBjYXNlIDk0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKTsKICAgICAgICAgIGNhc2UgOTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCk7CiAgICAgICAgICBjYXNlIDk2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKTsKICAgICAgICAgIGNhc2UgOTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpOwogICAgICAgICAgY2FzZSA5ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpOwogICAgICAgICAgY2FzZSA5OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpOwogICAgICAgICAgY2FzZSAxMDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCk7CiAgICAgICAgICBjYXNlIDEwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpOwogICAgICAgICAgY2FzZSAxMDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpOwogICAgICAgICAgY2FzZSAxMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKTsKICAgICAgICAgIGNhc2UgMTA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpOwogICAgICAgICAgY2FzZSAxMDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpOwogICAgICAgICAgY2FzZSAxMDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgICAgY2FzZSAxMDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpOwogICAgICAgICAgY2FzZSAxMDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKTsKICAgICAgICAgIGNhc2UgMTEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgICBjYXNlIDExMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpOwogICAgICAgICAgY2FzZSAxMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpOwogICAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKTsKICAgICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCk7CiAgICAgICAgICBjYXNlIDExNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKTsKICAgICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpOwogICAgICAgICAgY2FzZSAxMTc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCk7CiAgICAgICAgICBjYXNlIDExODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKTsKICAgICAgICAgIGNhc2UgMTE5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpOwogICAgICAgICAgY2FzZSAxMjA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKTsKICAgICAgICAgIGNhc2UgMTIxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpOwogICAgICAgICAgY2FzZSAxMjI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgICAgY2FzZSAxMjM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKTsKICAgICAgICAgIGNhc2UgMTI0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAgICAgICBjYXNlIDEyNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpOwogICAgICAgICAgY2FzZSAxMjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCk7CiAgICAgICAgICBjYXNlIDEyNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKTsKICAgICAgICAgIGNhc2UgMTI4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpOwogICAgICAgICAgY2FzZSAxMjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKTsKICAgICAgICAgIGNhc2UgMTMwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpOwogICAgICAgICAgY2FzZSAxMzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICBjYXNlIDEzMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCk7CiAgICAgICAgICBjYXNlIDEzMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCk7CiAgICAgICAgICBjYXNlIDEzNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCk7CiAgICAgICAgICBjYXNlIDEzNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCk7CiAgICAgICAgICBjYXNlIDEzNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCk7CiAgICAgICAgICBjYXNlIDEzNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgY2FzZSAxMzg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAgICAgICBjYXNlIDEzOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCk7CiAgICAgICAgICBjYXNlIDE0MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgY2FzZSAxNDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKTsKICAgICAgICAgIGNhc2UgMTQyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCk7CiAgICAgICAgICBjYXNlIDE0MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKTsKICAgICAgICAgIGNhc2UgMTQ0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpOwogICAgICAgICAgY2FzZSAxNDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICBjYXNlIDE0NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpOwogICAgICAgICAgY2FzZSAxNDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAgICAgICBjYXNlIDE0ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKTsKICAgICAgICAgIGNhc2UgMTQ5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIGNhc2UgMTUwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgICAgICAgIGNhc2UgMTUxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIGNhc2UgMTUyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIGNhc2UgMTUzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgICAgICAgIGNhc2UgMTU0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCk7CiAgICAgICAgICBjYXNlIDE1NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKTsKICAgICAgICAgIGNhc2UgMTU2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgICAgICAgIGNhc2UgMTU3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCk7CiAgICAgICAgICBjYXNlIDE1ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgY2FzZSAxNTk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKTsKICAgICAgICAgIGNhc2UgMTYwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpOwogICAgICAgICAgY2FzZSAxNjE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCk7CiAgICAgICAgICBjYXNlIDE2MjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKTsKICAgICAgICAgIGNhc2UgMTYzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCk7CiAgICAgICAgICBjYXNlIDE2NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKTsKICAgICAgICAgIGNhc2UgMTY1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpOwogICAgICAgICAgY2FzZSAxNjY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpOwogICAgICAgICAgY2FzZSAxNjc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpOwogICAgICAgICAgY2FzZSAxNjg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpOwogICAgICAgICAgY2FzZSAxNjk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpOwogICAgICAgICAgY2FzZSAxNzA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpOwogICAgICAgICAgY2FzZSAxNzE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKTsKICAgICAgICAgIGNhc2UgMTcyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgICAgICAgY2FzZSAxNzM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpOwogICAgICAgICAgY2FzZSAxNzQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKTsKICAgICAgICAgIGNhc2UgMTc1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCk7CiAgICAgICAgICBjYXNlIDE3NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpOwogICAgICAgICAgY2FzZSAxNzc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCk7CiAgICAgICAgICBjYXNlIDE3ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKTsKICAgICAgICAgIGNhc2UgMTc5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgICAgY2FzZSAxODA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKTsKICAgICAgICAgIGNhc2UgMTgxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpOwogICAgICAgICAgY2FzZSAxODI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCk7CiAgICAgICAgICBjYXNlIDE4MzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCk7CiAgICAgICAgICBjYXNlIDE4NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAgICAgICBjYXNlIDE4NToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgICBjYXNlIDE4NjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCk7CiAgICAgICAgICBjYXNlIDE4NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCk7CiAgICAgICAgICBjYXNlIDE4ODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpOwogICAgICAgICAgY2FzZSAxODk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCk7CiAgICAgICAgICBjYXNlIDE5MDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAgICAgICBjYXNlIDE5MToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpOwogICAgICAgICAgY2FzZSAxOTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKTsKICAgICAgICAgIGNhc2UgMTkzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAgICAgICBjYXNlIDE5NDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICAgIGNhc2UgMTk1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpOwogICAgICAgICAgY2FzZSAxOTY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCk7CiAgICAgICAgICBjYXNlIDE5NzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpOwogICAgICAgICAgY2FzZSAxOTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCk7CiAgICAgICAgICBjYXNlIDE5OToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgICAgICAgIGNhc2UgMjAwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKTsKICAgICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKTsKICAgICAgICAgIGNhc2UgMjAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKTsKICAgICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKTsKICAgICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMV8gPSAwOwogICAgICAgIGJpdEZpZWxkMl8gPSAwOwogICAgICAgIGJpdEZpZWxkM18gPSAwOwogICAgICAgIGJpdEZpZWxkNF8gPSAwOwogICAgICAgIGJpdEZpZWxkNV8gPSAwOwogICAgICAgIGJpdEZpZWxkNl8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMV8gIT0gMCkgeyBidWlsZFBhcnRpYWwxKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDIocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDNfICE9IDApIHsgYnVpbGRQYXJ0aWFsMyhyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkNF8gIT0gMCkgeyBidWlsZFBhcnRpYWw0KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQ1XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDUocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDZfICE9IDApIHsgYnVpbGRQYXJ0aWFsNihyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sQm9vbDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEJvb2wxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sQnl0ZXMyXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sQnl0ZXMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRG91YmxlM18gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xEb3VibGUzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRW51bTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEVudW00Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRml4ZWQzMjVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEZpeGVkMzI1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRml4ZWQ2NDZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbEZpeGVkNjQ2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRmxvYXQ3XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sRmxvYXQ3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sSW50MzI4XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sSW50MzI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sSW50NjQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sSW50NjQ5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sTWVzc2FnZTEwXyA9IGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuYnVpbGQoRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTZml4ZWQzMjExXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEJvb2xTZml4ZWQ2NDEyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ludDMyMTNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNpbnQzMjEzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU2ludDY0MTRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFNpbnQ2NDE0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sU3RyaW5nMTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFN0cmluZzE1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sVWludDMyMTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFVpbnQzMjE2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBCb29sVWludDY0MTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwQm9vbFVpbnQ2NDE3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyQm9vbDE4XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyQm9vbDE4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJCeXRlczE5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRW51bTIxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJGbG9hdDI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMySW50MzIyNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJJbnQzMjI1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMySW50NjQyNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJJbnQ2NDI2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuYnVpbGQoRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50MzIzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkMzJVaW50NjQzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjREb3VibGUzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEVudW0zOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDMyNDJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0SW50MzI0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NEludDY0NDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0SW50NjQ0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmJ1aWxkKEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50MzI0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50MzI1MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCb29sNTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkJvb2w1Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJCeXRlczUzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJ5dGVzNTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyQnl0ZXM1M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJEb3VibGU1NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJFbnVtNTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkVudW01NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDMyNTZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGaXhlZDY0NTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJGbG9hdDU4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyRmxvYXQ1OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJJbnQzMjU5XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50MzI1OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMySW50NjQ2MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuYnVpbGQoRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ZpeGVkNjQ2M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTaW50MzI2NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50MzJTaW50MzI2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyXyA9IGJpdEZpZWxkMl87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ludDY0NjVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU2ludDY0NjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU3RyaW5nNjZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyU3RyaW5nNjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyVWludDMyNjdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyVWludDMyNjdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyVWludDY0NjhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDMyVWludDY0NjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Qm9vbDY5XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRCb29sNjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Qnl0ZXM3MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEJ5dGVzNzBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RG91YmxlNzFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RG91YmxlNzEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RG91YmxlNzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RW51bTcyXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRFbnVtNzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQzMjczXyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRGaXhlZDMyNzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0Rml4ZWQ2NDc0XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwSW50NjRGaXhlZDY0NzRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0RmxvYXQ3NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEZsb2F0NzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0SW50MzI3Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDMyNzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0SW50NjQ3N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NEludDY0NzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0TWVzc2FnZTc4XyA9IGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmJ1aWxkKEZpZWxkTWFwSW50NjRNZXNzYWdlNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U2ludDMyODFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U2ludDMyODFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U2ludDY0ODJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U2ludDY0ODJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U3RyaW5nODNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0U3RyaW5nODNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0VWludDMyODRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0VWludDMyODRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0VWludDY0ODVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcEludDY0VWludDY0ODVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyQm9vbDg2XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJCb29sODZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRG91YmxlODhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRG91YmxlODhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRW51bTg5XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMySW50MzI5M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDMyOTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMySW50NjQ5NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMkludDY0OTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmJ1aWxkKEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkM18gPSBiaXRGaWVsZDNfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmJ1aWxkKEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XyA9IGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0VWludDMyMTE4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNmaXhlZDY0VWludDY0MTE5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJCb29sMTIwXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJCb29sMTIwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJCeXRlczEyMV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkJ5dGVzMTIxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyRG91YmxlMTIyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJFbnVtMTIzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJFbnVtMTIzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkZsb2F0MTI2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkludDMyMTI3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMkludDY0MTI4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsNChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDRfID0gYml0RmllbGQ0XzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmJ1aWxkKEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyU3RyaW5nMTM0XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlN0cmluZzEzNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qm9vbDEzN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRCeXRlczEzOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RW51bTE0MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RW51bTE0MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0RmxvYXQxNDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRGbG9hdDE0M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRJbnQzMjE0NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmJ1aWxkKEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9IGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQm9vbDE1NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdCeXRlczE1NV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRW51bTE1N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRW51bTE1N18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDUoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQ1XyA9IGJpdEZpZWxkNV87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDMyMTYxXyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nSW50MzIxNjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ0ludDY0MTYyXyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nSW50NjQxNjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5idWlsZChGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1VpbnQzMjE2OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkJvb2wxNzFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkJvb2wxNzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkJ5dGVzMTcyXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyQnl0ZXMxNzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJEb3VibGUxNzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkVudW0xNzRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkVudW0xNzRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyRmxvYXQxNzdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDMyMTc4XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMySW50MzIxNzhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMkludDY0MTc5XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMySW50NjQxNzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5idWlsZChGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50MzIxODNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTaW50NjQxODRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJTdHJpbmcxODVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50MzIxODZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50MzJVaW50NjQxODdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEJvb2wxODhfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEJvb2wxODhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0Qnl0ZXMxODlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjREb3VibGUxOTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEVudW0xOTFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEVudW0xOTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWw2KGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNl8gPSBiaXRGaWVsZDZfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCk7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRGbG9hdDE5NF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEZsb2F0MTk0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEludDMyMTk1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NEludDY0MTk2Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XyA9IGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuYnVpbGQoRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV8gPSBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKTsKICAgICAgICAgIHJlc3VsdC5maWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ludDMyMjAwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U2ludDY0MjAxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0U3RyaW5nMjAyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0VWludDMyMjAzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID0gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpOwogICAgICAgICAgcmVzdWx0LmZpZWxkTWFwVWludDY0VWludDY0MjA0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qnl0ZXM3MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qnl0ZXM3MCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZsb2F0NzUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50NjQ4MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U3RyaW5nODMoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sQm9vbDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJvb2wxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCb29sMV9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xCb29sMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sQnl0ZXMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sQnl0ZXMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRG91YmxlM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRG91YmxlM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xEb3VibGUzX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbERvdWJsZTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRW51bTRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xFbnVtNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEZpeGVkMzI1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRml4ZWQ2NDZfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sRml4ZWQ2NDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEZsb2F0N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sRmxvYXQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sRmxvYXQ3X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbEZsb2F0N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQzMjhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEludDMyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbEludDMyOF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xJbnQzMjhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQ2NDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQ2NDlfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sSW50NjQ5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkMzIxMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ZpeGVkMzIxMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTZml4ZWQzMjExX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ZpeGVkNjQxMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ZpeGVkNjQxMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTZml4ZWQ2NDEyX18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OAogICAgICAgICAgICAgIGNhc2UgMTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQzMjEzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50MzIxM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sU2ludDMyMTNfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sU2ludDMyMTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDYKICAgICAgICAgICAgICBjYXNlIDExNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFNpbnQ2NDE0X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFNpbnQ2NDE0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xTdHJpbmcxNV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBCb29sU3RyaW5nMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFN0cmluZzE1X18uZ2V0S2V5KCksIGZpZWxkTWFwQm9vbFN0cmluZzE1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyCiAgICAgICAgICAgICAgY2FzZSAxMzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBCb29sVWludDMyMTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50MzIxNl9fLmdldEtleSgpLCBmaWVsZE1hcEJvb2xVaW50MzIxNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMAogICAgICAgICAgICAgIGNhc2UgMTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBCb29sVWludDY0MTdfXy5nZXRLZXkoKSwgZmllbGRNYXBCb29sVWludDY0MTdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzgKICAgICAgICAgICAgICBjYXNlIDE0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJvb2wxOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJCb29sMThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgICBjYXNlIDE1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyQnl0ZXMxOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCeXRlczE5X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQKICAgICAgICAgICAgICBjYXNlIDE2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJEb3VibGUyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjIKICAgICAgICAgICAgICBjYXNlIDE3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkVudW0yMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkVudW0yMV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzAKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzgKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODYKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyRmxvYXQyNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRmxvYXQyNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQzMjI1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQzMjI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMySW50MzIyNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMgogICAgICAgICAgICAgIGNhc2UgMjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMySW50NjQyNl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxOAogICAgICAgICAgICAgIGNhc2UgMjI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjI2CiAgICAgICAgICAgICAgY2FzZSAyMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMzQKICAgICAgICAgICAgICBjYXNlIDI0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ludDMyMzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQyCiAgICAgICAgICAgICAgY2FzZSAyNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MAogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1OAogICAgICAgICAgICAgIGNhc2UgMjY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJVaW50MzIzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDMyVWludDMyMzNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNjYKICAgICAgICAgICAgICBjYXNlIDI3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDY0MzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjc0CiAgICAgICAgICAgICAgY2FzZSAyODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCb29sMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRCb29sMzVfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0Qm9vbDM1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRCeXRlczM2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjkwCiAgICAgICAgICAgICAgY2FzZSAyOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0RG91YmxlMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3X18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjk4CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RW51bTM4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0RW51bTM4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA2CiAgICAgICAgICAgICAgY2FzZSAzMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE0CiAgICAgICAgICAgICAgY2FzZSAzMjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIyCiAgICAgICAgICAgICAgY2FzZSAzMzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMwCiAgICAgICAgICAgICAgY2FzZSAzMzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0SW50MzI0Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzgKICAgICAgICAgICAgICBjYXNlIDM0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0SW50NjQ0M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgMzU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTQKICAgICAgICAgICAgICBjYXNlIDM2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2MgogICAgICAgICAgICAgIGNhc2UgMzcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzcwCiAgICAgICAgICAgICAgY2FzZSAzNzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM3OAogICAgICAgICAgICAgIGNhc2UgMzg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzODYKICAgICAgICAgICAgICBjYXNlIDM5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXy5nZXRLZXkoKSwgZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzOTQKICAgICAgICAgICAgICBjYXNlIDQwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwX18uZ2V0S2V5KCksIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBGaXhlZDY0VWludDY0NTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV9fLmdldEtleSgpLCBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxMAogICAgICAgICAgICAgIGNhc2UgNDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCb29sNTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyQm9vbDUyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE4CiAgICAgICAgICAgICAgY2FzZSA0MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJCeXRlczUzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkJ5dGVzNTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MjYKICAgICAgICAgICAgICBjYXNlIDQzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkRvdWJsZTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkRvdWJsZTU0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJEb3VibGU1NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQzNAogICAgICAgICAgICAgIGNhc2UgNDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJFbnVtNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkVudW01NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMyRW51bTU1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDQyCiAgICAgICAgICAgICAgY2FzZSA0NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkMzI1Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NTAKICAgICAgICAgICAgICBjYXNlIDQ1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQ2NDU3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGaXhlZDY0NTdfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1OAogICAgICAgICAgICAgIGNhc2UgNDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyRmxvYXQ1OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJGbG9hdDU4X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJGbG9hdDU4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDY2CiAgICAgICAgICAgICAgY2FzZSA0NzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkludDMyNTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV9fLmdldEtleSgpLCBmaWVsZE1hcEludDMySW50MzI1OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ3NAogICAgICAgICAgICAgIGNhc2UgNDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJJbnQ2NDYwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMySW50NjQ2MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMkludDY0NjBfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMkludDY0NjBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0ODIKICAgICAgICAgICAgICBjYXNlIDQ5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyTWVzc2FnZTYxX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OTAKICAgICAgICAgICAgICBjYXNlIDQ5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDk4CiAgICAgICAgICAgICAgY2FzZSA1MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fLmdldEtleSgpLCBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNgogICAgICAgICAgICAgIGNhc2UgNTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQzMjY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQzMjY0X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTaW50MzI2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxNAogICAgICAgICAgICAgIGNhc2UgNTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQ2NDY1X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50MzJTaW50NjQ2NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyMgogICAgICAgICAgICAgIGNhc2UgNTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyU3RyaW5nNjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyU3RyaW5nNjZfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlN0cmluZzY2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTMwCiAgICAgICAgICAgICAgY2FzZSA1Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDMyNjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyVWludDMyNjdfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlVpbnQzMjY3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTM4CiAgICAgICAgICAgICAgY2FzZSA1NDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQzMlVpbnQ2NDY4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTQ2CiAgICAgICAgICAgICAgY2FzZSA1NTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEJvb2w2OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEJvb2w2OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Qm9vbDY5X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRCb29sNjlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NTQKICAgICAgICAgICAgICBjYXNlIDU2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEJ5dGVzNzBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Qnl0ZXM3MF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0Qnl0ZXM3MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU2MgogICAgICAgICAgICAgIGNhc2UgNTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NERvdWJsZTcxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTcwCiAgICAgICAgICAgICAgY2FzZSA1Nzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEVudW03Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEVudW03MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0RW51bTcyX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRFbnVtNzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NzgKICAgICAgICAgICAgICBjYXNlIDU4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0Rml4ZWQzMjczX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEZpeGVkMzI3M19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4NgogICAgICAgICAgICAgIGNhc2UgNTk0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRGaXhlZDY0NzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0Rml4ZWQ2NDc0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTk0CiAgICAgICAgICAgICAgY2FzZSA2MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRGbG9hdDc1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NEZsb2F0NzVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MDIKICAgICAgICAgICAgICBjYXNlIDYxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0SW50MzI3Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2X18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRJbnQzMjc2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjEwCiAgICAgICAgICAgICAgY2FzZSA2MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0SW50NjQ3N19fLmdldEtleSgpLCBmaWVsZE1hcEludDY0SW50NjQ3N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYxOAogICAgICAgICAgICAgIGNhc2UgNjI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0TWVzc2FnZTc4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0TWVzc2FnZTc4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYyNgogICAgICAgICAgICAgIGNhc2UgNjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkMzI3OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MzQKICAgICAgICAgICAgICBjYXNlIDY0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18uZ2V0S2V5KCksIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQyCiAgICAgICAgICAgICAgY2FzZSA2NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNpbnQzMjgxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUwCiAgICAgICAgICAgICAgY2FzZSA2NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDY0ODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDY0ODJfXy5nZXRLZXkoKSwgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjU4CiAgICAgICAgICAgICAgY2FzZSA2NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTdHJpbmc4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U3RyaW5nODMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRTdHJpbmc4M19fLmdldEtleSgpLCBmaWVsZE1hcEludDY0U3RyaW5nODNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NjYKICAgICAgICAgICAgICBjYXNlIDY3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0VWludDMyODRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50MzI4NF9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0VWludDMyODRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NzQKICAgICAgICAgICAgICBjYXNlIDY4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcEludDY0VWludDY0ODVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50NjQ4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50NjQ4NV9fLmdldEtleSgpLCBmaWVsZE1hcEludDY0VWludDY0ODVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2ODIKICAgICAgICAgICAgICBjYXNlIDY5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQm9vbDg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkJvb2w4Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY5MAogICAgICAgICAgICAgIGNhc2UgNjk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjk4CiAgICAgICAgICAgICAgY2FzZSA3MDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MDYKICAgICAgICAgICAgICBjYXNlIDcxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRW51bTg5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRW51bTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkVudW04OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcxNAogICAgICAgICAgICAgIGNhc2UgNzIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIyCiAgICAgICAgICAgICAgY2FzZSA3MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MzAKICAgICAgICAgICAgICBjYXNlIDczODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczOAogICAgICAgICAgICAgIGNhc2UgNzQ2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMkludDMyOTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NDYKICAgICAgICAgICAgICBjYXNlIDc1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzU0CiAgICAgICAgICAgICAgY2FzZSA3NjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYyCiAgICAgICAgICAgICAgY2FzZSA3NzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MAogICAgICAgICAgICAgIGNhc2UgNzc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODYKICAgICAgICAgICAgICBjYXNlIDc5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTQKICAgICAgICAgICAgICBjYXNlIDgwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAyCiAgICAgICAgICAgICAgY2FzZSA4MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTAKICAgICAgICAgICAgICBjYXNlIDgxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgODI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBjYXNlIDgzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODM0CiAgICAgICAgICAgICAgY2FzZSA4NDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg0MgogICAgICAgICAgICAgIGNhc2UgODUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NTAKICAgICAgICAgICAgICBjYXNlIDg1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODU4CiAgICAgICAgICAgICAgY2FzZSA4NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg2NgogICAgICAgICAgICAgIGNhc2UgODc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NzQKICAgICAgICAgICAgICBjYXNlIDg4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4ODIKICAgICAgICAgICAgICBjYXNlIDg5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTAKICAgICAgICAgICAgICBjYXNlIDg5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg5OAogICAgICAgICAgICAgIGNhc2UgOTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwNgogICAgICAgICAgICAgIGNhc2UgOTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkxNAogICAgICAgICAgICAgIGNhc2UgOTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNV9fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTIyCiAgICAgICAgICAgICAgY2FzZSA5MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MzAKICAgICAgICAgICAgICBjYXNlIDkzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN19fLmdldEtleSgpLCBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTM4CiAgICAgICAgICAgICAgY2FzZSA5NDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NDYKICAgICAgICAgICAgICBjYXNlIDk1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfXy5nZXRLZXkoKSwgZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk1NAogICAgICAgICAgICAgIGNhc2UgOTYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCb29sMTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJCb29sMTIwX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyQm9vbDEyMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2MgogICAgICAgICAgICAgIGNhc2UgOTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJCeXRlczEyMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk3MAogICAgICAgICAgICAgIGNhc2UgOTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJEb3VibGUxMjJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRG91YmxlMTIyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk3OAogICAgICAgICAgICAgIGNhc2UgOTg2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRW51bTEyM19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJFbnVtMTIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJFbnVtMTIzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRW51bTEyM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4NgogICAgICAgICAgICAgIGNhc2UgOTk0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk5NAogICAgICAgICAgICAgIGNhc2UgMTAwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDAyCiAgICAgICAgICAgICAgY2FzZSAxMDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZsb2F0MTI2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJGbG9hdDEyNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwMTAKICAgICAgICAgICAgICBjYXNlIDEwMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQzMjEyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMkludDMyMTI3X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMySW50MzIxMjdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDE4CiAgICAgICAgICAgICAgY2FzZSAxMDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50NjQxMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQ2NDEyOF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMkludDY0MTI4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAyNgogICAgICAgICAgICAgIGNhc2UgMTAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAzNAogICAgICAgICAgICAgIGNhc2UgMTA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNDIKICAgICAgICAgICAgICBjYXNlIDEwNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDUwCiAgICAgICAgICAgICAgY2FzZSAxMDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJTaW50MzIxMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDU4CiAgICAgICAgICAgICAgY2FzZSAxMDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50MzJTaW50NjQxMzNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDY2CiAgICAgICAgICAgICAgY2FzZSAxMDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNzQKICAgICAgICAgICAgICBjYXNlIDEwODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJVaW50MzIxMzVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDMyMTM1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwODIKICAgICAgICAgICAgICBjYXNlIDEwOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50MzJVaW50NjQxMzZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyVWludDY0MTM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwOTAKICAgICAgICAgICAgICBjYXNlIDEwOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRCb29sMTM3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEJvb2wxMzdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRCb29sMTM3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA5OAogICAgICAgICAgICAgIGNhc2UgMTEwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRCeXRlczEzOF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCeXRlczEzOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjREb3VibGUxMzlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RG91YmxlMTM5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMTQKICAgICAgICAgICAgICBjYXNlIDExMjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRFbnVtMTQwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEVudW0xNDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRFbnVtMTQwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEyMgogICAgICAgICAgICAgIGNhc2UgMTEzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTMwCiAgICAgICAgICAgICAgY2FzZSAxMTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMzgKICAgICAgICAgICAgICBjYXNlIDExNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RmxvYXQxNDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRGbG9hdDE0M19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0NgogICAgICAgICAgICAgIGNhc2UgMTE1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDMyMTQ0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRJbnQzMjE0NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNTQKICAgICAgICAgICAgICBjYXNlIDExNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRJbnQ2NDE0NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEludDY0MTQ1X18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTYyCiAgICAgICAgICAgICAgY2FzZSAxMTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTcwCiAgICAgICAgICAgICAgY2FzZSAxMTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N19fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE3OAogICAgICAgICAgICAgIGNhc2UgMTE4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhfXy5nZXRLZXkoKSwgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExODYKICAgICAgICAgICAgICBjYXNlIDExOTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50MzIxNDlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExOTQKICAgICAgICAgICAgICBjYXNlIDEyMDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTaW50NjRTaW50NjQxNTBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDY0MTUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fLmdldEtleSgpLCBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMDIKICAgICAgICAgICAgICBjYXNlIDEyMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxMAogICAgICAgICAgICAgIGNhc2UgMTIxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0VWludDMyMTUyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIxOAogICAgICAgICAgICAgIGNhc2UgMTIyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50NjQxNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18uZ2V0S2V5KCksIGZpZWxkTWFwU2ludDY0VWludDY0MTUzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyNgogICAgICAgICAgICAgIGNhc2UgMTIzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCb29sMTU0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCb29sMTU0X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMzQKICAgICAgICAgICAgICBjYXNlIDEyNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdCeXRlczE1NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjQyCiAgICAgICAgICAgICAgY2FzZSAxMjUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI1MAogICAgICAgICAgICAgIGNhc2UgMTI1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRW51bTE1N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdFbnVtMTU3X18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nRW51bTE1N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyNTgKICAgICAgICAgICAgICBjYXNlIDEyNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjY2CiAgICAgICAgICAgICAgY2FzZSAxMjc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI3NAogICAgICAgICAgICAgIGNhc2UgMTI4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRmxvYXQxNjBfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyODIKICAgICAgICAgICAgICBjYXNlIDEyOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDMyMTYxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDMyMTYxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyOTAKICAgICAgICAgICAgICBjYXNlIDEyOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ludDY0MTYyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyOTgKICAgICAgICAgICAgICBjYXNlIDEzMDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMwNgogICAgICAgICAgICAgIGNhc2UgMTMxNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMxNAogICAgICAgICAgICAgIGNhc2UgMTMyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMyMgogICAgICAgICAgICAgIGNhc2UgMTMzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzMwCiAgICAgICAgICAgICAgY2FzZSAxMzM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N19fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMzgKICAgICAgICAgICAgICBjYXNlIDEzNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfXy5nZXRLZXkoKSwgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzQ2CiAgICAgICAgICAgICAgY2FzZSAxMzU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nVWludDMyMTY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV9fLmdldEtleSgpLCBmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNTQKICAgICAgICAgICAgICBjYXNlIDEzNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwX18uZ2V0S2V5KCksIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2MgogICAgICAgICAgICAgIGNhc2UgMTM3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyQm9vbDE3MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyQm9vbDE3MV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzcwCiAgICAgICAgICAgICAgY2FzZSAxMzc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJCeXRlczE3Ml9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNzgKICAgICAgICAgICAgICBjYXNlIDEzODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJEb3VibGUxNzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRG91YmxlMTczX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyRG91YmxlMTczX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM4NgogICAgICAgICAgICAgIGNhc2UgMTM5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkVudW0xNzRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkVudW0xNzRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzk0CiAgICAgICAgICAgICAgY2FzZSAxNDAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MDIKICAgICAgICAgICAgICBjYXNlIDE0MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQxMAogICAgICAgICAgICAgIGNhc2UgMTQxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJGbG9hdDE3N19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyRmxvYXQxNzdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDE4CiAgICAgICAgICAgICAgY2FzZSAxNDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMySW50MzIxNzhfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQzMjE3OF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMkludDMyMTc4X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQyNgogICAgICAgICAgICAgIGNhc2UgMTQzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDY0MTc5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMySW50NjQxNzlfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0MzQKICAgICAgICAgICAgICBjYXNlIDE0NDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NDIKICAgICAgICAgICAgICBjYXNlIDE0NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDUwCiAgICAgICAgICAgICAgY2FzZSAxNDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ1OAogICAgICAgICAgICAgIGNhc2UgMTQ2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50MzIxODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyU2ludDMyMTgzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2NgogICAgICAgICAgICAgIGNhc2UgMTQ3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDMyU2ludDY0MTg0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ3NAogICAgICAgICAgICAgIGNhc2UgMTQ4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlN0cmluZzE4NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJTdHJpbmcxODVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDgyCiAgICAgICAgICAgICAgY2FzZSAxNDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDMyMTg2X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJVaW50MzIxODZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDkwCiAgICAgICAgICAgICAgY2FzZSAxNDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDMyVWludDY0MTg3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50MzJVaW50NjQxODdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDk4CiAgICAgICAgICAgICAgY2FzZSAxNTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Qm9vbDE4OF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCb29sMTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCb29sMTg4X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0Qm9vbDE4OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MDYKICAgICAgICAgICAgICBjYXNlIDE1MTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Qnl0ZXMxODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRCeXRlczE4OV9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUxNAogICAgICAgICAgICAgIGNhc2UgMTUyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0RG91YmxlMTkwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjREb3VibGUxOTBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTIyCiAgICAgICAgICAgICAgY2FzZSAxNTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0RW51bTE5MV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRFbnVtMTkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRFbnVtMTkxX18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0RW51bTE5MV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1MzAKICAgICAgICAgICAgICBjYXNlIDE1Mzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUzOAogICAgICAgICAgICAgIGNhc2UgMTU0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRGbG9hdDE5NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NTQKICAgICAgICAgICAgICBjYXNlIDE1NjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRJbnQzMjE5NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEludDMyMTk1X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0SW50MzIxOTVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTYyCiAgICAgICAgICAgICAgY2FzZSAxNTcwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0SW50NjQxOTZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NEludDY0MTk2X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU3MAogICAgICAgICAgICAgIGNhc2UgMTU3ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU3OAogICAgICAgICAgICAgIGNhc2UgMTU4NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1ODYKICAgICAgICAgICAgICBjYXNlIDE1OTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5X18uZ2V0S2V5KCksIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTk0CiAgICAgICAgICAgICAgY2FzZSAxNjAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTaW50MzIyMDBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAyCiAgICAgICAgICAgICAgY2FzZSAxNjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDY0MjAxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXy5nZXRLZXkoKSwgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjEwCiAgICAgICAgICAgICAgY2FzZSAxNjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U3RyaW5nMjAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MTgKICAgICAgICAgICAgICBjYXNlIDE2MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MjYKICAgICAgICAgICAgICBjYXNlIDE2MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50NjQyMDRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fLmdldEtleSgpLCBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDJfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDNfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDRfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDVfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDZfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEJvb2xCb29sMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xCb29sMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCb29sMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQm9vbDFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sQm9vbDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xCb29sMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEJvb2wxXyA9IGZpZWxkTWFwQm9vbEJvb2wxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQm9vbDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sQm9vbDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCb29sMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQm9vbDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xCb29sMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEJvb2xCb29sMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sQm9vbDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwQm9vbEJvb2wxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBCb29sQm9vbDFPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgZmllbGRfbWFwX2Jvb2xfYm9vbF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwQm9vbEJvb2wxT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJvb2wxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJvb2wxKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBmaWVsZF9tYXBfYm9vbF9ib29sXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEJvb2wxKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCb29sMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IGZpZWxkX21hcF9ib29sX2Jvb2xfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sQm9vbDEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQm9vbDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEJ5dGVzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sQnl0ZXMyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xCeXRlczJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xCeXRlczJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xCeXRlczJfID0gZmllbGRNYXBCb29sQnl0ZXMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sQnl0ZXMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEJ5dGVzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xCeXRlczIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEJ5dGVzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBCb29sQnl0ZXMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEJvb2xCeXRlczJPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBCb29sQnl0ZXMyT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sQnl0ZXMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xCeXRlczIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBieXRlcyZndDsgZmllbGRfbWFwX2Jvb2xfYnl0ZXNfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sQnl0ZXMyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEJ5dGVzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfYm9vbF9ieXRlc18yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xCeXRlczIoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9ib29sX2J5dGVzXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEJ5dGVzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sQnl0ZXMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEJvb2xEb3VibGUzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xEb3VibGUzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbERvdWJsZTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbERvdWJsZTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbERvdWJsZTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xEb3VibGUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRG91YmxlM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbERvdWJsZTNfID0gZmllbGRNYXBCb29sRG91YmxlM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbERvdWJsZTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRG91YmxlM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRG91YmxlMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xEb3VibGUzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfYm9vbF9kb3VibGVfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBCb29sRG91YmxlM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9ib29sX2RvdWJsZV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBCb29sRG91YmxlM09yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbERvdWJsZTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRG91YmxlMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRG91YmxlMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGRvdWJsZSZndDsgZmllbGRfbWFwX2Jvb2xfZG91YmxlXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbERvdWJsZTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xEb3VibGUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sRW51bTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRW51bTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRW51bTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEVudW00XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEVudW00RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRW51bTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xFbnVtNF8gPSBmaWVsZE1hcEJvb2xFbnVtNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEVudW00XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEVudW00Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xFbnVtNCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwQm9vbEVudW00KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwQm9vbEVudW00TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEJvb2xFbnVtNE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEJvb2xFbnVtNFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBCb29sRW51bTRPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRW51bTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRW51bTRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRW51bTRWYWx1ZU9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xFbnVtNCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfYm9vbF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEVudW00KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEJvb2xFbnVtNE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwQm9vbEVudW00VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9ib29sX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sRW51bTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwQm9vbEVudW00TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xFbnVtNCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sRW51bTRWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xFbnVtNFZhbHVlKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2Jvb2xfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xFbnVtNFZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEVudW00KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sRml4ZWQzMjVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRml4ZWQzMjVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQzMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZpeGVkMzI1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEZpeGVkMzI1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZpeGVkMzI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sRml4ZWQzMjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xGaXhlZDMyNV8gPSBmaWVsZE1hcEJvb2xGaXhlZDMyNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEZpeGVkMzI1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xGaXhlZDMyNSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZpeGVkMzI1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQzMjVPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xGaXhlZDMyNU9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDMyXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbEZpeGVkMzI1KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkMzI1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQzMl81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xGaXhlZDMyNSgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDMyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkMzJfNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sRml4ZWQzMjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQzMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xGaXhlZDY0Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xGaXhlZDY0Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGaXhlZDY0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQ2NDZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRml4ZWQ2NDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sRml4ZWQ2NDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xGaXhlZDY0Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbEZpeGVkNjQ2XyA9IGZpZWxkTWFwQm9vbEZpeGVkNjQ2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRml4ZWQ2NDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEZpeGVkNjQ2KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xGaXhlZDY0Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xGaXhlZDY0NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sRml4ZWQ2NDZPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZpeGVkNjQ2KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9maXhlZDY0XzYgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEZpeGVkNjQ2KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGaXhlZDY0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ZpeGVkNjRfNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sRml4ZWQ2NDYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRml4ZWQ2NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBCb29sRmxvYXQ3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRmxvYXQ3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbEZsb2F0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRmxvYXQ3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sRmxvYXQ3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xGbG9hdDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xGbG9hdDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xGbG9hdDdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xGbG9hdDdfID0gZmllbGRNYXBCb29sRmxvYXQ3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sRmxvYXQ3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEZsb2F0N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEJvb2xGbG9hdDcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEZsb2F0N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBCb29sRmxvYXQ3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9ib29sX2Zsb2F0XzcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwQm9vbEZsb2F0N09yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBCb29sRmxvYXQ3T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sRmxvYXQ3KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sRmxvYXQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEZsb2F0NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfYm9vbF9mbG9hdF83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xGbG9hdDcoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBmbG9hdCZndDsgZmllbGRfbWFwX2Jvb2xfZmxvYXRfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sRmxvYXQ3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xGbG9hdDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEJvb2xJbnQzMjhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEludDMyOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDMyOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sSW50MzI4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQzMjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xJbnQzMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xJbnQzMjhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xJbnQzMjhfID0gZmllbGRNYXBCb29sSW50MzI4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sSW50MzI4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbEludDMyOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sSW50MzI4KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEludDMyOCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sSW50MzI4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbEludDMyOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sSW50MzI4T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDMyOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQzMjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfaW50MzJfOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sSW50MzI4KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbEludDMyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQzMl84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xJbnQzMjgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50MzI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sSW50NjQ5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xJbnQ2NDlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xJbnQ2NDlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbEludDY0OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sSW50NjQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sSW50NjQ5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sSW50NjQ5XyA9IGZpZWxkTWFwQm9vbEludDY0OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbEludDY0OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbEludDY0OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xJbnQ2NDlPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbEludDY0OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9pbnQ2NF85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbEludDY0OU9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfaW50NjRfOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sSW50NjQ5KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sSW50NjQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX2ludDY0XzkgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbEludDY0OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xJbnQ2NDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBCb29sTWVzc2FnZTEwQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBCb29sTWVzc2FnZTEwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlciBmaWVsZE1hcEJvb2xNZXNzYWdlMTBDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBCb29sTWVzc2FnZTEwQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBCb29sTWVzc2FnZTEwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbE1lc3NhZ2UxMF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sTWVzc2FnZTEwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBCb29sTWVzc2FnZTEwQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xNZXNzYWdlMTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwQm9vbE1lc3NhZ2UxME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBCb29sTWVzc2FnZTEwT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sTWVzc2FnZTEwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbE1lc3NhZ2UxMENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sTWVzc2FnZTEwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xNZXNzYWdlMTAoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfYm9vbF9tZXNzYWdlXzEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sTWVzc2FnZTEwKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9ib29sX21lc3NhZ2VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xNZXNzYWdlMTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2Jvb2xfbWVzc2FnZV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xNZXNzYWdlMTBCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBib29sZWFuIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbE1lc3NhZ2UxMCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ZpeGVkMzIxMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQzMjExRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfID0gZmllbGRNYXBCb29sU2ZpeGVkMzIxMV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNmaXhlZDMyMTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQzMl8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkMzIxMU9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkMzJfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDMyMTEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sU2ZpeGVkMzIxMSgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDMyXzExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sU2ZpeGVkMzIxMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQzMjExKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sU2ZpeGVkNjQxMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ZpeGVkNjQxMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sU2ZpeGVkNjQxMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfID0gZmllbGRNYXBCb29sU2ZpeGVkNjQxMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNmaXhlZDY0MTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sU2ZpeGVkNjQxMk9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ZpeGVkNjRfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NmaXhlZDY0XzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sU2ZpeGVkNjQxMigKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zZml4ZWQ2NF8xMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbFNmaXhlZDY0MTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ZpeGVkNjQxMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwQm9vbFNpbnQzMjEzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQzMjEzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQzMjEzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTaW50MzIxM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xTaW50MzIxM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ludDMyMTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xTaW50MzIxM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwQm9vbFNpbnQzMjEzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBCb29sU2ludDMyMTNfID0gZmllbGRNYXBCb29sU2ludDMyMTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTaW50MzIxM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwQm9vbFNpbnQzMjEzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEJvb2xTaW50MzIxM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sU2ludDMyMTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQzMjEzT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sU2ludDMyMTNPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEJvb2xTaW50MzIxMygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50MzIxMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDMyXzEzID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sU2ludDMyMTMoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDMyMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQzMl8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbFNpbnQzMjEzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQzMjEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBCb29sU2ludDY0MTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sU2ludDY0MTRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sU2ludDY0MTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFNpbnQ2NDE0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFNpbnQ2NDE0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU2ludDY0MTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTaW50NjQxNF8gPSBmaWVsZE1hcEJvb2xTaW50NjQxNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFNpbnQ2NDE0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU2ludDY0MTRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBCb29sU2ludDY0MTQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFNpbnQ2NDE0T3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEJvb2xTaW50NjQxNE9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTaW50NjQxNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xTaW50NjQxNCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF9zaW50NjRfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xTaW50NjQxNCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU2ludDY0MTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3NpbnQ2NF8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwQm9vbFNpbnQ2NDE0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFNpbnQ2NDE0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEJvb2xTdHJpbmcxNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEJvb2xTdHJpbmcxNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFN0cmluZzE1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTdHJpbmcxNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFN0cmluZzE1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sU3RyaW5nMTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xTdHJpbmcxNV8gPSBmaWVsZE1hcEJvb2xTdHJpbmcxNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFN0cmluZzE1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFN0cmluZzE1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9ib29sX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBCb29sU3RyaW5nMTVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sU3RyaW5nMTUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEJvb2xTdHJpbmcxNU9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFN0cmluZzE1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sU3RyaW5nMTUoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBCb29sU3RyaW5nMTUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xTdHJpbmcxNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHN0cmluZyZndDsgZmllbGRfbWFwX2Jvb2xfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBCb29sU3RyaW5nMTUoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfYm9vbF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEJvb2xTdHJpbmcxNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFN0cmluZzE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBCb29sVWludDMyMTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sVWludDMyMTZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDMyMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFVpbnQzMjE2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwQm9vbFVpbnQzMjE2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50MzIxNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwQm9vbFVpbnQzMjE2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBCb29sVWludDMyMTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEJvb2xVaW50MzIxNl8gPSBmaWVsZE1hcEJvb2xVaW50MzIxNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwQm9vbFVpbnQzMjE2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEJvb2xVaW50MzIxNigKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBCb29sVWludDMyMTZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBCb29sVWludDMyMTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwQm9vbFVpbnQzMjE2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDMyMTZPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEJvb2xVaW50MzIxNk9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQzMl8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwQm9vbFVpbnQzMjE2KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQzMjE2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDMyJmd0OyBmaWVsZF9tYXBfYm9vbF91aW50MzJfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEJvb2xVaW50MzIxNigKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50MzIxNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQzMiZndDsgZmllbGRfbWFwX2Jvb2xfdWludDMyXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sVWludDMyMTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDMyMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEJvb2xVaW50NjQxN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEJvb2xVaW50NjQxN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEJvb2xVaW50NjQxN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDY0MTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBCb29sVWludDY0MTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBCb29sVWludDY0MTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEJvb2xVaW50NjQxN18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwQm9vbFVpbnQ2NDE3XyA9IGZpZWxkTWFwQm9vbFVpbnQ2NDE3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBCb29sVWludDY0MTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBCb29sVWludDY0MTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwQm9vbFVpbnQ2NDE3KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEJvb2xVaW50NjQxN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEJvb2xVaW50NjQxNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBCb29sVWludDY0MTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBCb29sVWludDY0MTdPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfYm9vbF91aW50NjRfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3T3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwQm9vbFVpbnQ2NDE3KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwQm9vbFVpbnQ2NDE3KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEJvb2xVaW50NjQxNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2Jvb2xfdWludDY0XzE3ID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBCb29sVWludDY0MTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBCb29sVWludDY0MTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEZpeGVkMzJCb29sMThfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkJvb2wxOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkJvb2wxOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQm9vbDE4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJCb29sMThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJCb29sMThfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJCb29sMThfID0gZmllbGRNYXBGaXhlZDMyQm9vbDE4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQm9vbDE4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyQm9vbDE4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJCb29sMThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDMyQm9vbDE4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJCb29sMTgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJCb29sMTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJvb2wxOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMTggPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJCb29sMTgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQm9vbDE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYm9vbF8xOCA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkJvb2wxOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCb29sMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJCeXRlczE5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJCeXRlczE5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV8gPSBmaWVsZE1hcEZpeGVkMzJCeXRlczE5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyQnl0ZXMxOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9ieXRlc18xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2J5dGVzXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyQnl0ZXMxOSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkJ5dGVzMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJCeXRlczE5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJCeXRlczE5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyRG91YmxlMjBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8gPSBmaWVsZE1hcEZpeGVkMzJEb3VibGUyMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2RvdWJsZV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZG91YmxlXzIwID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyRG91YmxlMjAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9kb3VibGVfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJEb3VibGUyMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyRW51bTIxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJFbnVtMjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRW51bTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJFbnVtMjFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkVudW0yMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRW51bTIxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyRW51bTIxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRW51bTIxXyA9IGZpZWxkTWFwRml4ZWQzMkVudW0yMV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkVudW0yMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkMzJFbnVtMjFNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2VudW1fMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRW51bTIxVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwRml4ZWQzMkVudW0yMU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9lbnVtXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRW51bTIxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEZpeGVkMzJFbnVtMjFWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkVudW0yMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDMyRW51bTIxTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJFbnVtMjEoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRW51bTIxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZW51bV8yMSA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkVudW0yMVZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkVudW0yMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMl8gPSBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDMyXzIyID0gMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZml4ZWQzMl8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkMzJfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzXyA9IGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9maXhlZDY0XzIzID0gMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ZpeGVkNjRfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJGaXhlZDY0MjMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGbG9hdDI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJGbG9hdDI0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJGbG9hdDI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfID0gZmllbGRNYXBGaXhlZDMyRmxvYXQyNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkZsb2F0MjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkMzJGbG9hdDI0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwRml4ZWQzMkZsb2F0MjRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2Zsb2F0XzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyRmxvYXQyNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdF8yNCA9IDI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkZsb2F0MjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfZmxvYXRfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJGbG9hdDI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMySW50MzIyNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkludDMyMjVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50MzIyNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMySW50MzIyNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMkludDMyMjVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJJbnQzMjI1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMySW50MzIyNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfID0gZmllbGRNYXBGaXhlZDMySW50MzIyNV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkludDMyMjVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMySW50MzIyNSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMySW50MzIyNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDMyXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDMyMjVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMkludDMyMjUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDMyMjUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJJbnQzMjI1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQzMl8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMkludDMyMjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50MzIyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMkludDY0MjZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMkludDY0MjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMkludDY0MjZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMySW50NjQyNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMkludDY0MjZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XyA9IGZpZWxkTWFwRml4ZWQzMkludDY0MjZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJJbnQ2NDI2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMkludDY0MjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMkludDY0MjZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMkludDY0MjYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9pbnQ2NF8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMySW50NjQyNk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMySW50NjQyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMkludDY0MjYoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2ID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMySW50NjQyNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyID0gbmV3IEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX21lc3NhZ2VfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkMzJfbWVzc2FnZV8yNyA9IDI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0J1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XyA9IGZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQzMl8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkMzJfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV8gPSBmaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ZpeGVkNjRfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50MzIzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfID0gZmllbGRNYXBGaXhlZDMyU2ludDMyMzBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50MzIzMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQzMl8zMCA9IDMwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDMyMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50MzJfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50MzIzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkMzJTaW50NjQzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfID0gZmllbGRNYXBGaXhlZDMyU2ludDY0MzFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkMzJTaW50NjQzMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3NpbnQ2NF8zMSA9IDMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zaW50NjRfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTaW50NjQzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc2ludDY0XzMxID0gMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU2ludDY0MzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkMzJTdHJpbmczMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXyA9IGZpZWxkTWFwRml4ZWQzMlN0cmluZzMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDMyU3RyaW5nMzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkMzJfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkMzJTdHJpbmczMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJTdHJpbmczMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlN0cmluZzMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDMyVWludDMyMzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyVWludDMyMzNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDMyMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyVWludDMyMzNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18gPSBmaWVsZE1hcEZpeGVkMzJVaW50MzIzM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDMyXzMzID0gMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzM09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50MzJfMzMgPSAzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDMyVWludDMyMzNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50MzIzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDMyMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQzMl8zMyA9IDMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDMyVWludDY0MzRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDMyVWludDY0MzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDMyVWludDY0MzREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDMyVWludDY0MzRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8gPSBmaWVsZE1hcEZpeGVkMzJVaW50NjQzNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkMzJfdWludDY0XzM0ID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDMyVWludDY0MzRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDMyVWludDY0MzQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDMyX3VpbnQ2NF8zNCA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQzMl91aW50NjRfMzQgPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkMzJVaW50NjQzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qm9vbDM1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Qm9vbDM1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRCb29sMzVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEJvb2wzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJvb2wzNV8gPSBmaWVsZE1hcEZpeGVkNjRCb29sMzVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCb29sMzVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXzM1ID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEZpeGVkNjRCb29sMzVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYm9vbF8zNSA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJvb2wzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Jvb2xfMzUgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRCb29sMzUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qm9vbDM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRCeXRlczM2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRCeXRlczM2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfID0gZmllbGRNYXBGaXhlZDY0Qnl0ZXMzNl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2ID0gMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNigpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfYnl0ZXNfMzYgPSAzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRCeXRlczM2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRCeXRlczM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjREb3VibGUzN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0RG91YmxlMzdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjREb3VibGUzN18gPSBmaWVsZE1hcEZpeGVkNjREb3VibGUzN18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjREb3VibGUzNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEZpeGVkNjREb3VibGUzN09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjREb3VibGUzNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZG91YmxlXzM3ID0gMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0RG91YmxlMzcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2RvdWJsZV8zNyA9IDM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RG91YmxlMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEVudW0zOF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEVudW0zOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RW51bTM4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRFbnVtMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRFbnVtMzhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRFbnVtMzhfID0gZmllbGRNYXBGaXhlZDY0RW51bTM4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RW51bTM4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0RW51bTM4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcEZpeGVkNjRFbnVtMzhNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBGaXhlZDY0RW51bTM4VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4ID0gMzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRFbnVtMzgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEVudW0zOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBGaXhlZDY0RW51bTM4TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RW51bTM4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZW51bV8zOCA9IDM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEVudW0zOFZhbHVlKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEVudW0zOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2VudW1fMzggPSAzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRFbnVtMzhWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRFbnVtMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlfID0gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDMyXzM5ID0gMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkMzJfMzkgPSAzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwXyA9IGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ZpeGVkNjRfNDAgPSA0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9maXhlZDY0XzQwID0gNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZml4ZWQ2NF80MCA9IDQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV8gPSBmaWVsZE1hcEZpeGVkNjRGbG9hdDQxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0RmxvYXQ0MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBGaXhlZDY0RmxvYXQ0MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfZmxvYXRfNDEgPSA0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9mbG9hdF80MSA9IDQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEZsb2F0NDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRGbG9hdDQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2Zsb2F0XzQxID0gNDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDMyNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50MzI0MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXyA9IGZpZWxkTWFwRml4ZWQ2NEludDMyNDJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQzMjQyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50MzJfNDIgPSA0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0SW50MzI0Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDMyNDJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDMyXzQyID0gNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50MzI0MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDMyNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQzMjQyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQzMl80MiA9IDQyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NEludDMyNDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50MzI0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NEludDY0NDNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0SW50NjQ0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXyA9IGZpZWxkTWFwRml4ZWQ2NEludDY0NDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRJbnQ2NDQzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0M01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NEludDY0NDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X2ludDY0XzQzID0gNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0SW50NjQ0MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9pbnQ2NF80MyA9IDQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NEludDY0NDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNDMgPSA0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRJbnQ2NDQzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NEludDY0NDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlciBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9tZXNzYWdlXzQ0ID0gNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDQgPSA0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ZpeGVkNjRfbWVzc2FnZV80NCA9IDQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRNZXNzYWdlNDRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBsb25nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfID0gZmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQzMl80NSA9IDQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDUgPSA0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDMyXzQ1ID0gNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfID0gZmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkNjRfNDYgPSA0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2ID0gNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zZml4ZWQ2NF80NiA9IDQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRTaW50MzI0N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfID0gZmllbGRNYXBGaXhlZDY0U2ludDMyNDdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTaW50MzI0N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDcgPSA0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50MzI0NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDMyXzQ3ID0gNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U2ludDMyNDcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDMyNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQzMl80NyA9IDQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0U2ludDY0NDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U2ludDY0NDhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8gPSBmaWVsZE1hcEZpeGVkNjRTaW50NjQ0OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc2ludDY0XzQ4ID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDggPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U2ludDY0NDgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3NpbnQ2NF80OCA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0U3RyaW5nNDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8gPSBmaWVsZE1hcEZpeGVkNjRTdHJpbmc0OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3N0cmluZ180OSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ZpeGVkNjRfc3RyaW5nXzQ5ID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDkgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBGaXhlZDY0VWludDMyNTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDMyNTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDMyNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBGaXhlZDY0VWludDMyNTBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8gPSBmaWVsZE1hcEZpeGVkNjRVaW50MzI1MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQzMl81MCA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50MzJfNTAgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDMyXzUwID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0VWludDMyNTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDMyNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBGaXhlZDY0VWludDY0NTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBGaXhlZDY0VWludDY0NTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEZpeGVkNjRVaW50NjQ1MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXyA9IGZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBGaXhlZDY0VWludDY0NTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBGaXhlZDY0VWludDY0NTFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfZml4ZWQ2NF91aW50NjRfNTEgPSA1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9maXhlZDY0X3VpbnQ2NF81MSA9IDUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ZpeGVkNjRfdWludDY0XzUxID0gNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBGaXhlZDY0VWludDY0NTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBGaXhlZDY0VWludDY0NTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQm9vbDUyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQm9vbDUyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJvb2w1Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJCb29sNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyQm9vbDUyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJvb2w1Ml8gPSBmaWVsZE1hcEludDMyQm9vbDUyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkJvb2w1Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQm9vbDUyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyQm9vbDUyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQm9vbDUyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQm9vbDUyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX2ludDMyX2Jvb2xfNTIgPSA1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwSW50MzJCb29sNTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBJbnQzMkJvb2w1Mk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkJvb2w1MigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCb29sNTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyQm9vbDUyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfaW50MzJfYm9vbF81MiA9IDUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJCb29sNTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJvb2w1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkJ5dGVzNTNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkJ5dGVzNTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJCeXRlczUzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyQnl0ZXM1M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyQnl0ZXM1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJCeXRlczUzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkJ5dGVzNTNfID0gZmllbGRNYXBJbnQzMkJ5dGVzNTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyQnl0ZXM1M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkJ5dGVzNTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50MzJfYnl0ZXNfNTMgPSA1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50MzJCeXRlczUzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDMyQnl0ZXM1M09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwSW50MzJCeXRlczUzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX2ludDMyX2J5dGVzXzUzID0gNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkJ5dGVzNTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJCeXRlczUzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkJ5dGVzNTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQzMl9ieXRlc181MyA9IDUzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJCeXRlczUzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyQnl0ZXM1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBJbnQzMkRvdWJsZTU0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRG91YmxlNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJEb3VibGU1NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRG91YmxlNTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJEb3VibGU1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJEb3VibGU1NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJEb3VibGU1NF8gPSBmaWVsZE1hcEludDMyRG91YmxlNTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRG91YmxlNTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRG91YmxlNTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJEb3VibGU1NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDMyX2RvdWJsZV81NCA9IDU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcEludDMyRG91YmxlNTRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQzMkRvdWJsZTU0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpIHsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJEb3VibGU1NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTQgPSA1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyRG91YmxlNTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRG91YmxlNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50MzJfZG91YmxlXzU0ID0gNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkRvdWJsZTU0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkRvdWJsZTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJFbnVtNTVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkVudW01NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJFbnVtNTVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRW51bTU1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkVudW01NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJFbnVtNTVfID0gZmllbGRNYXBJbnQzMkVudW01NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJFbnVtNTVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkVudW01NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwSW50MzJFbnVtNTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJFbnVtNTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcEludDMyRW51bTU1VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBJbnQzMkVudW01NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkVudW01NVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEludDMyRW51bTU1VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkVudW01NVZhbHVlT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkVudW01NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRW51bTU1KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQzMl9lbnVtXzU1ID0gNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkVudW01NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQzMkVudW01NU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NVZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50MzJfZW51bV81NSA9IDU1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJFbnVtNTVWYWx1ZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJFbnVtNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDMyX2VudW1fNTUgPSA1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyRW51bTU1VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkVudW01NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDMyNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZpeGVkMzI1NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJGaXhlZDMyNTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyRml4ZWQzMjU2XyA9IGZpZWxkTWFwSW50MzJGaXhlZDMyNTZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQzMjU2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJGaXhlZDMyNTYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQzMl81NiA9IDU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQzMjU2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkMzI1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKSB7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQzMjU2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9maXhlZDMyXzU2ID0gNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMkZpeGVkMzI1NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkMzJfNTYgPSA1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyRml4ZWQzMjU2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDMyNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRml4ZWQ2NDU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRml4ZWQ2NDU3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJGaXhlZDY0NTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyRml4ZWQ2NDU3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZpeGVkNjQ1N18gPSBmaWVsZE1hcEludDMyRml4ZWQ2NDU3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMkZpeGVkNjQ1N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyRml4ZWQ2NDU3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ZpeGVkNjRfNTcgPSA1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTdPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkZpeGVkNjQ1N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGaXhlZDY0NTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyRml4ZWQ2NDU3KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZml4ZWQ2NF81NyA9IDU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJGaXhlZDY0NTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZpeGVkNjQ1NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyRmxvYXQ1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkZsb2F0NThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkZsb2F0NThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJGbG9hdDU4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyRmxvYXQ1OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZsb2F0NThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyRmxvYXQ1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJGbG9hdDU4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMkZsb2F0NThfID0gZmllbGRNYXBJbnQzMkZsb2F0NThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyRmxvYXQ1OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMkZsb2F0NThNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyRmxvYXQ1OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50MzJfZmxvYXRfNTggPSA1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwSW50MzJGbG9hdDU4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkZsb2F0NTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OCA9IDU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJGbG9hdDU4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyRmxvYXQ1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDMyX2Zsb2F0XzU4ID0gNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMkZsb2F0NTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJGbG9hdDU4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMkludDMyNTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkludDMyNTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDMyNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQzMjU5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQzMjU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkludDMyNTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50MzI1OV8gPSBmaWVsZE1hcEludDMySW50MzI1OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQzMjU5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50MzI1OSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50MzI1OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDMyNTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX2ludDMyXzU5ID0gNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJJbnQzMjU5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMySW50MzI1OU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfaW50MzJfNTkgPSA1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMkludDMyNTlPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMySW50MzI1OSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50MzI1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDMyNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OSA9IDU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJJbnQzMjU5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQzMjU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMkludDY0NjBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMkludDY0NjBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMkludDY0NjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJJbnQ2NDYwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJJbnQ2NDYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMkludDY0NjBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMySW50NjQ2MF8gPSBmaWVsZE1hcEludDMySW50NjQ2MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJJbnQ2NDYwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMySW50NjQ2ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMkludDY0NjBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX2ludDY0XzYwID0gNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJJbnQ2NDYwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMkludDY0NjBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMySW50NjQ2MCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMkludDY0NjAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9pbnQ2NF82MCA9IDYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJJbnQ2NDYwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJJbnQ2NDYwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfaW50NjRfNjAgPSA2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMySW50NjQ2MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMySW50NjQ2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBJbnQzMk1lc3NhZ2U2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEludDMyTWVzc2FnZTYxQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyTWVzc2FnZTYxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDMyX21lc3NhZ2VfNjEgPSA2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBJbnQzMk1lc3NhZ2U2MUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwSW50MzJNZXNzYWdlNjFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJNZXNzYWdlNjFDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJNZXNzYWdlNjEoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50MzJfbWVzc2FnZV82MSA9IDYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJNZXNzYWdlNjEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyTWVzc2FnZTYxKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQzMl9tZXNzYWdlXzYxID0gNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJNZXNzYWdlNjFCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMk1lc3NhZ2U2MSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlNmaXhlZDMyNjJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8gPSBmaWVsZE1hcEludDMyU2ZpeGVkMzI2Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQzMjYyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDMyXzYyID0gNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2Mk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkMzJfNjIgPSA2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDMyNjJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkMzI2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDMyNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQzMl82MiA9IDYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQzMjYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNmaXhlZDY0NjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlNmaXhlZDY0NjNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18gPSBmaWVsZE1hcEludDMyU2ZpeGVkNjQ2M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlNmaXhlZDY0NjNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNmaXhlZDY0NjMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zZml4ZWQ2NF82MyA9IDYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ZpeGVkNjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ZpeGVkNjQ2MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50MzJTaW50MzI2NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlNpbnQzMjY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlNpbnQzMjY0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ludDMyNjRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTaW50MzI2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50MzJTaW50MzI2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50MzJTaW50MzI2NF8gPSBmaWVsZE1hcEludDMyU2ludDMyNjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDMyNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDMyU2ludDMyNjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJTaW50MzI2NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50MzJTaW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJTaW50MzI2NCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50MzI2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyU2ludDMyNjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQzMjY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQzMlNpbnQ2NDY1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyU2ludDY0NjVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyU2ludDY0NjVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTaW50NjQ2NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlNpbnQ2NDY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlNpbnQ2NDY1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlNpbnQ2NDY1XyA9IGZpZWxkTWFwSW50MzJTaW50NjQ2NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTaW50NjQ2NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTaW50NjQ2NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlNpbnQ2NDY1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJTaW50NjQ2NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDMyU2ludDY0NjVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU2ludDY0NjUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1ID0gNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlNpbnQ2NDY1KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTaW50NjQ2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zaW50NjRfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDMyU2ludDY0NjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlNpbnQ2NDY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcEludDMyU3RyaW5nNjZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50MzJTdHJpbmc2NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlN0cmluZzY2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlN0cmluZzY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlN0cmluZzY2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlN0cmluZzY2XyA9IGZpZWxkTWFwSW50MzJTdHJpbmc2Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJTdHJpbmc2Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDMyU3RyaW5nNjZPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyU3RyaW5nNjYoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQzMl9zdHJpbmdfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyU3RyaW5nNjYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJTdHJpbmc2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDMyX3N0cmluZ182NiA9IDY2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50MzJTdHJpbmc2NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyU3RyaW5nNjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50MzJfc3RyaW5nXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQzMlN0cmluZzY2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlN0cmluZzY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQzMlVpbnQzMjY3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDMyVWludDMyNjdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDMyVWludDMyNjdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50MzI2N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQzMlVpbnQzMjY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQzMlVpbnQzMjY3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQzMlVpbnQzMjY3XyA9IGZpZWxkTWFwSW50MzJVaW50MzI2N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50MzI2N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJVaW50MzI2NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50MzJVaW50MzI2N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50MzJfNjcgPSA2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDMyVWludDMyNjdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfaW50MzJfdWludDMyXzY3ID0gNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQzMlVpbnQzMjY3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQzMjY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQzMl82NyA9IDY3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJVaW50MzI2NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDMyNjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDMyVWludDY0NjhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50MzJVaW50NjQ2OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50MzJVaW50NjQ2OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQzMlVpbnQ2NDY4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDMyVWludDY0NjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDMyVWludDY0NjhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDMyVWludDY0NjhfID0gZmllbGRNYXBJbnQzMlVpbnQ2NDY4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQzMlVpbnQ2NDY4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQzMlVpbnQ2NDY4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDMyVWludDY0NjhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQzMlVpbnQ2NDY4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50MzJVaW50NjQ2OE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDMyVWludDY0NjgoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50MzJVaW50NjQ2OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQzMl91aW50NjRfNjggPSA2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDMyVWludDY0NjgoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQzMlVpbnQ2NDY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDMyX3VpbnQ2NF82OCA9IDY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50MzJVaW50NjQ2OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDMyVWludDY0NjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcEludDY0Qm9vbDY5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEJvb2w2OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qm9vbDY5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0Qm9vbDY5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEJvb2w2OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEJvb2w2OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCb29sNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0Qm9vbDY5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEJvb2w2OV8gPSBmaWVsZE1hcEludDY0Qm9vbDY5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJvb2w2OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Qm9vbDY5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEJvb2w2OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwSW50NjRCb29sNjlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcEludDY0Qm9vbDY5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfaW50NjRfYm9vbF82OSA9IDY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRCb29sNjkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJvb2w2OSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCb29sNjkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX2ludDY0X2Jvb2xfNjkgPSA2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0Qm9vbDY5KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ib29sXzY5ID0gNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEJvb2w2OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Qm9vbDY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0Qnl0ZXM3MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Qnl0ZXM3MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEJ5dGVzNzBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRCeXRlczcwXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Qnl0ZXM3MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRCeXRlczcwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEJ5dGVzNzBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0Qnl0ZXM3MF8gPSBmaWVsZE1hcEludDY0Qnl0ZXM3MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRCeXRlczcwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRCeXRlczcwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwSW50NjRCeXRlczcwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcEludDY0Qnl0ZXM3ME9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9ieXRlc183MCA9IDcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRCeXRlczcwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRCeXRlczcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfaW50NjRfYnl0ZXNfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0Qnl0ZXM3MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEJ5dGVzNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwSW50NjREb3VibGU3MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RG91YmxlNzFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NERvdWJsZTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RG91YmxlNzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NERvdWJsZTcxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RG91YmxlNzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0RG91YmxlNzFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0RG91YmxlNzFfID0gZmllbGRNYXBJbnQ2NERvdWJsZTcxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NERvdWJsZTcxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjREb3VibGU3MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcEludDY0RG91YmxlNzFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwSW50NjREb3VibGU3MU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9kb3VibGVfNzEgPSA3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjREb3VibGU3MSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjREb3VibGU3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX2ludDY0X2RvdWJsZV83MSA9IDcxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjREb3VibGU3MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RG91YmxlNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfaW50NjRfZG91YmxlXzcxID0gNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NERvdWJsZTcxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NERvdWJsZTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEVudW03Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRFbnVtNzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEVudW03MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRFbnVtNzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRFbnVtNzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RW51bTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEVudW03Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRFbnVtNzJfID0gZmllbGRNYXBJbnQ2NEVudW03Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRFbnVtNzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEVudW03MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RW51bTcyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwSW50NjRFbnVtNzJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcEludDY0RW51bTcyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEVudW03MlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBJbnQ2NEVudW03MlZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEVudW03MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRFbnVtNzIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0RW51bTcyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBJbnQ2NEVudW03Mk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9pbnQ2NF9lbnVtXzcyID0gNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEVudW03MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBmaWVsZE1hcEludDY0RW51bTcyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRFbnVtNzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwSW50NjRFbnVtNzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRFbnVtNzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX2ludDY0X2VudW1fNzIgPSA3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0RW51bTcyVmFsdWUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEVudW03MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfaW50NjRfZW51bV83MiA9IDcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRFbnVtNzJWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RW51bTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQzMjczRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfID0gZmllbGRNYXBJbnQ2NEZpeGVkMzI3M18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDMyNzNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQzMl83MyA9IDczOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkMzI3M09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkMzJfNzMgPSA3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Rml4ZWQzMjczKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDMyNzMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczID0gNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NEZpeGVkMzI3MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQzMjczKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0Rml4ZWQ2NDc0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfID0gZmllbGRNYXBJbnQ2NEZpeGVkNjQ3NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGaXhlZDY0NzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ZpeGVkNjRfNzQgPSA3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGaXhlZDY0NzQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0Rml4ZWQ2NDc0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9maXhlZDY0Xzc0ID0gNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NCA9IDc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRGaXhlZDY0NzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEZsb2F0NzVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEZsb2F0NzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRGbG9hdDc1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0RmxvYXQ3NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0RmxvYXQ3NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRGbG9hdDc1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEZsb2F0NzVfID0gZmllbGRNYXBJbnQ2NEZsb2F0NzVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0RmxvYXQ3NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRGbG9hdDc1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcEludDY0RmxvYXQ3NU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBJbnQ2NEZsb2F0NzVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRGbG9hdDc1KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX2ludDY0X2Zsb2F0Xzc1ID0gNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEZsb2F0NzUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0RmxvYXQ3NSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRGbG9hdDc1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfaW50NjRfZmxvYXRfNzUgPSA3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0RmxvYXQ3NSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEZsb2F0NzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0SW50MzI3Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0SW50MzI3Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50MzI3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NEludDMyNzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NEludDMyNzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0SW50MzI3Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRJbnQzMjc2XyA9IGZpZWxkTWFwSW50NjRJbnQzMjc2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NEludDMyNzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0SW50MzI3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0SW50MzI3NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NEludDMyNzZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50MzI3Nk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRJbnQzMjc2T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X2ludDMyXzc2ID0gNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NEludDMyNzYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDMyNzYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQzMl83NiA9IDc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRJbnQzMjc2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQzMjc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfaW50MzJfNzYgPSA3Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0SW50MzI3NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50MzI3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwSW50NjRJbnQ2NDc3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRJbnQ2NDc3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRJbnQ2NDc3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50NjQ3N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0SW50NjQ3N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0SW50NjQ3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRJbnQ2NDc3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NEludDY0NzdfID0gZmllbGRNYXBJbnQ2NEludDY0NzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0SW50NjQ3N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0SW50NjQ3N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRJbnQ2NDc3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRJbnQ2NDc3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0SW50NjQ3N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0SW50NjQ3N09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83NyA9IDc3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NEludDY0NzdPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NEludDY0NzcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NEludDY0NzcoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X2ludDY0Xzc3ID0gNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NEludDY0NzcoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRJbnQ2NDc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfaW50NjRfNzcgPSA3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0SW50NjQ3NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0SW50NjQ3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NE1lc3NhZ2U3OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfaW50NjRfbWVzc2FnZV83OCA9IDc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcEludDY0TWVzc2FnZTc4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcEludDY0TWVzc2FnZTc4Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRNZXNzYWdlNzhDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4ID0gNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRNZXNzYWdlNzgoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0TWVzc2FnZTc4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0TWVzc2FnZTc4KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX2ludDY0X21lc3NhZ2VfNzggPSA3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8gPSBmaWVsZE1hcEludDY0U2ZpeGVkMzI3OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTZml4ZWQzMjc5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTZml4ZWQzMjc5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQzMl83OSA9IDc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQzMjc5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzkgPSA3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDMyXzc5ID0gNzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0U2ZpeGVkNjQ4MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXyA9IGZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ZpeGVkNjRfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zZml4ZWQ2NF84MCA9IDgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NmaXhlZDY0XzgwID0gODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNmaXhlZDY0ODAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcEludDY0U2ludDMyODFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50MzI4MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50MzI4MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFNpbnQzMjgxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U2ludDMyODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0U2ludDMyODFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U2ludDMyODFfID0gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFNpbnQzMjgxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwSW50NjRTaW50MzI4MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFNpbnQzMjgxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDMyODEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDMyXzgxID0gODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFNpbnQzMjgxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTaW50MzI4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50MzJfODEgPSA4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcEludDY0U2ludDMyODEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQzMjgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U2ludDY0ODJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U2ludDY0ODJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBJbnQ2NFNpbnQ2NDgyXyA9IGZpZWxkTWFwSW50NjRTaW50NjQ4Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRTaW50NjQ4Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcEludDY0U2ludDY0ODJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTaW50NjQ4MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zaW50NjRfODIgPSA4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRTaW50NjQ4Mk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfc2ludDY0XzgyID0gODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFNpbnQ2NDgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3NpbnQ2NF84MiA9IDgyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTaW50NjQ4MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0U2ludDY0ODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwSW50NjRTdHJpbmc4M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0U3RyaW5nODNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBJbnQ2NFN0cmluZzgzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0U3RyaW5nODNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFN0cmluZzgzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0U3RyaW5nODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0U3RyaW5nODNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0U3RyaW5nODNfID0gZmllbGRNYXBJbnQ2NFN0cmluZzgzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFN0cmluZzgzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRTdHJpbmc4M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFN0cmluZzgzKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMgPSA4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfaW50NjRfc3RyaW5nXzgzID0gODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcEludDY0U3RyaW5nODNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRTdHJpbmc4MygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFN0cmluZzgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX2ludDY0X3N0cmluZ184MyA9IDgzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRTdHJpbmc4MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRTdHJpbmc4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwSW50NjRVaW50MzI4NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQzMjg0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFVpbnQzMjg0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICAgIGlmIChmaWVsZE1hcEludDY0VWludDMyODRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50MzI4NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwSW50NjRVaW50MzI4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwSW50NjRVaW50MzI4NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwSW50NjRVaW50MzI4NF8gPSBmaWVsZE1hcEludDY0VWludDMyODRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcEludDY0VWludDMyODRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcEludDY0VWludDMyODRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcEludDY0VWludDMyODRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50MzI4NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50MzJfODQgPSA4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcEludDY0VWludDMyODQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBJbnQ2NFVpbnQzMjg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NCA9IDg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwSW50NjRVaW50MzI4NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDMyODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcEludDY0VWludDY0ODVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwSW50NjRVaW50NjQ4NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwSW50NjRVaW50NjQ4NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0VWludDY0ODVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcEludDY0VWludDY0ODVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcEludDY0VWludDY0ODVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcEludDY0VWludDY0ODVfID0gZmllbGRNYXBJbnQ2NFVpbnQ2NDg1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBJbnQ2NFVpbnQ2NDg1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwSW50NjRVaW50NjQ4NU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX2ludDY0X3VpbnQ2NF84NSA9IDg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9pbnQ2NF91aW50NjRfODUgPSA4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcEludDY0VWludDY0ODUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBJbnQ2NFVpbnQ2NDg1KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcEludDY0VWludDY0ODUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1ID0gODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBJbnQ2NFVpbnQ2NDg1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwSW50NjRVaW50NjQ4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCb29sODZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkJvb2w4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJCb29sODZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XyA9IGZpZWxkTWFwU2ZpeGVkMzJCb29sODZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyQm9vbDg2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJCb29sODYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYm9vbF84NiA9IDg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4Nk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDMyQm9vbDg2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJvb2w4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCb29sODYoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ib29sXzg2ID0gODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkJvb2w4NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQm9vbDg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkJ5dGVzODdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18gPSBmaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9ieXRlc184NyA9IDg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfYnl0ZXNfODcgPSA4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyQnl0ZXM4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2J5dGVzXzg3ID0gODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkJ5dGVzODcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBmaWVsZE1hcFNmaXhlZDMyRG91YmxlODhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4XyA9IGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZG91YmxlXzg4ID0gODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDMyRG91YmxlODhPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkgewogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2RvdWJsZV84OCA9IDg4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9kb3VibGVfODggPSA4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRG91YmxlODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRW51bTg5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyRW51bTg5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMkVudW04OV8gPSBmaWVsZE1hcFNmaXhlZDMyRW51bTg5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkVudW04OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJFbnVtODkoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2VudW1fODkgPSA4OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRW51bTg5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNmaXhlZDMyRW51bTg5TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5VmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9lbnVtXzg5ID0gODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkVudW04OVZhbHVlKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkVudW04OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZW51bV84OSA9IDg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJFbnVtODlWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRW51bTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfID0gZmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5ME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDMyXzkwID0gOTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpIHsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfOTAgPSA5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQzMl85MCA9IDkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXyA9IGZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZml4ZWQ2NF85MSA9IDkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTEoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XzkxID0gOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMkZsb2F0OTJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8gPSBmaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9mbG9hdF85MiA9IDkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2Zsb2F0XzkyID0gOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIgPSA5Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkZsb2F0OTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMySW50MzI5M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50MzI5M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50MzI5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDMyOTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDMyOTNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50MzI5M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDMyOTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50MzJfOTMgPSA5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQzMl85MyA9IDkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMySW50MzI5M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50MzI5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzID0gOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMkludDMyOTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDMyOTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMySW50NjQ5NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMkludDY0OTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMkludDY0OTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMySW50NjQ5NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0XyA9IGZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMkludDY0OTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfaW50NjRfOTQgPSA5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMySW50NjQ5NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMySW50NjQ5NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0ID0gOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMkludDY0OTQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMkludDY0OTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9pbnQ2NF85NCA9IDk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQyXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfbWVzc2FnZV85NSA9IDk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9tZXNzYWdlXzk1ID0gOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTUgPSA5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2XyA9IGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfOTYgPSA5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NiA9IDk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5Nk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKSB7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDMyXzk2ID0gOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3XyA9IGZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ZpeGVkNjRfOTcgPSA5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5NygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NmaXhlZDY0Xzk3ID0gOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85NyA9IDk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyU2ludDMyOThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4XyA9IGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOTggPSA5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc2ludDMyXzk4ID0gOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQzMl85OCA9IDk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlfID0gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zaW50NjRfOTkgPSA5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OSA9IDk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU2ludDY0OTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF8gPSBmaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl9zdHJpbmdfMTAwID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwME9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3N0cmluZ18xMDAgPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXyA9IGZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50MzJfMTAxID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDEgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDMyXzEwMSA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl8gPSBmaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkMzJfdWludDY0XzEwMiA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfID0gZmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Jvb2xfMTAzID0gMTAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDMgPSAxMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEJvb2wxMDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ib29sXzEwMyA9IDEwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNF8gPSBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2J5dGVzXzEwNCA9IDEwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0ID0gMTA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9ieXRlc18xMDQgPSAxMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEJ5dGVzMTA0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV8gPSBmaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZG91YmxlXzEwNSA9IDEwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1ID0gMTA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2RvdWJsZV8xMDUgPSAxMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0RW51bTEwNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0RW51bTEwNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2XyA9IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZW51bV8xMDYgPSAxMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBTZml4ZWQ2NEVudW0xMDZWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9lbnVtXzEwNiA9IDEwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0RW51bTEwNigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RW51bTEwNlZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2VudW1fMTA2ID0gMTA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEVudW0xMDYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3XyA9IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQzMl8xMDcgPSAxMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkMzJfMTA3ID0gMTA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDMyXzEwNyA9IDEwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfID0gZmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ZpeGVkNjRfMTA4ID0gMTA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDggPSAxMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9maXhlZDY0XzEwOCA9IDEwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOV8gPSBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9mbG9hdF8xMDkgPSAxMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5ID0gMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2Zsb2F0XzEwOSA9IDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDMyMTEwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMF8gPSBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDMyXzExMCA9IDExMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50MzJfMTEwID0gMTEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50MzIxMTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFfID0gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NEludDY0MTExXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfaW50NjRfMTExID0gMTExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X2ludDY0XzExMSA9IDExMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0SW50NjQxMTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9pbnQ2NF8xMTEgPSAxMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NEludDY0MTExKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyID0gbmV3IEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9tZXNzYWdlXzExMiA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfbWVzc2FnZV8xMTIgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NmaXhlZDY0X21lc3NhZ2VfMTEyID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM18gPSBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDMyXzExMyA9IDExMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDMyMTEzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzID0gMTEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRfID0gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfMTE0ID0gMTE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NmaXhlZDY0XzExNCA9IDExNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTQgPSAxMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQ2NDExNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XyA9IGZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDMyXzExNSA9IDExNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTUgPSAxMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50MzJfMTE1ID0gMTE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XyA9IGZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3NpbnQ2NF8xMTYgPSAxMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2ID0gMTE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc2ludDY0XzExNiA9IDExNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN18gPSBmaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExNyA9IDExNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3N0cmluZ18xMTcgPSAxMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF9zdHJpbmdfMTE3ID0gMTE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfID0gZmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50MzJfMTE4ID0gMTE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDMyXzExOCA9IDExODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMTggPSAxMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfID0gZmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ZpeGVkNjRfdWludDY0XzExOSA9IDExOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTkgPSAxMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zZml4ZWQ2NF91aW50NjRfMTE5ID0gMTE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGZpZWxkTWFwU2ludDMyQm9vbDEyMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJCb29sMTIwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCb29sMTIwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJvb2wxMjBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyQm9vbDEyMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyQm9vbDEyMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyQm9vbDEyMF8gPSBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJvb2wxMjBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkJvb2wxMjAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyQm9vbDEyME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQzMkJvb2wxMjBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTaW50MzJCb29sMTIwT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyQm9vbDEyMCgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCb29sMTIwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDMyX2Jvb2xfMTIwID0gMTIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyQm9vbDEyMCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJvb2wxMjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYm9vbF8xMjAgPSAxMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJCb29sMTIwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQm9vbDEyMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJCeXRlczEyMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJCeXRlczEyMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXyA9IGZpZWxkTWFwU2ludDMyQnl0ZXMxMjFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkJ5dGVzMTIxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3NpbnQzMl9ieXRlc18xMjEgPSAxMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDMyX2J5dGVzXzEyMSA9IDEyMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkJ5dGVzMTIxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJCeXRlczEyMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50MzJfYnl0ZXNfMTIxID0gMTIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyQnl0ZXMxMjEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJEb3VibGUxMjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJEb3VibGUxMjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkRvdWJsZTEyMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXyA9IGZpZWxkTWFwU2ludDMyRG91YmxlMTIyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJEb3VibGUxMjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDMyX2RvdWJsZV8xMjIgPSAxMjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZG91YmxlXzEyMiA9IDEyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRG91YmxlMTIyKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3NpbnQzMl9kb3VibGVfMTIyID0gMTIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRG91YmxlMTIyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJEb3VibGUxMjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkVudW0xMjNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRW51bTEyM18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRW51bTEyM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJFbnVtMTIzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkVudW0xMjNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkVudW0xMjNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkVudW0xMjNfID0gZmllbGRNYXBTaW50MzJFbnVtMTIzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJFbnVtMTIzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRW51bTEyM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDMyRW51bTEyM01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDMyX2VudW1fMTIzID0gMTIzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkVudW0xMjNWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTaW50MzJFbnVtMTIzTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQzMl9lbnVtXzEyMyA9IDEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkVudW0xMjMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU2ludDMyRW51bTEyM1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJFbnVtMTIzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQzMkVudW0xMjNNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRW51bTEyMygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkVudW0xMjMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50MzJfZW51bV8xMjMgPSAxMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJFbnVtMTIzVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJFbnVtMTIzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGaXhlZDMyMTI0XyA9IGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDMyXzEyNCA9IDEyNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkgewogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMjQgPSAxMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkMzJfMTI0ID0gMTI0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRml4ZWQzMjEyNCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVfID0gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGaXhlZDY0MTI1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJGaXhlZDY0MTI1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNSA9IDEyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ZpeGVkNjRfMTI1ID0gMTI1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMkZsb2F0MTI2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyRmxvYXQxMjZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyRmxvYXQxMjZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkZsb2F0MTI2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJGbG9hdDEyNl8gPSBmaWVsZE1hcFNpbnQzMkZsb2F0MTI2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJGbG9hdDEyNl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDMyRmxvYXQxMjZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTaW50MzJGbG9hdDEyNk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNiA9IDEyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKSB7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkZsb2F0MTI2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQzMl9mbG9hdF8xMjYgPSAxMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJGbG9hdDEyNigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJGbG9hdDEyNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfZmxvYXRfMTI2ID0gMTI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyRmxvYXQxMjYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyRmxvYXQxMjYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDMyMTI3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMkludDMyMTI3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMySW50MzIxMjdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMkludDMyMTI3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJJbnQzMjEyN18gPSBmaWVsZE1hcFNpbnQzMkludDMyMTI3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQzMjEyN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMkludDMyMTI3KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDMyXzEyNyA9IDEyNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQzMjEyN09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJJbnQzMjEyNygpIHsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50MzIxMjcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkgewogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQzMjEyNygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfaW50MzJfMTI3ID0gMTI3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMySW50MzIxMjcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjcgPSAxMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJJbnQzMjEyNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDMyMTI3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMySW50NjQxMjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJJbnQ2NDEyOERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMySW50NjQxMjhfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMkludDY0MTI4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMySW50NjQxMjhfID0gZmllbGRNYXBTaW50MzJJbnQ2NDEyOF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMySW50NjQxMjhfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9pbnQ2NF8xMjggPSAxMjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDMySW50NjQxMjhPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMySW50NjQxMjgoKSB7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMkludDY0MTI4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJJbnQ2NDEyOCgpIHsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX2ludDY0XzEyOCA9IDEyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMkludDY0MTI4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMySW50NjQxMjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlciBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIgPSBuZXcgRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDMyX21lc3NhZ2VfMTI5ID0gMTI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50MzJfbWVzc2FnZV8xMjkgPSAxMjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJNZXNzYWdlMTI5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQzMl9tZXNzYWdlXzEyOSA9IDEyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJNZXNzYWdlMTI5QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfID0gZmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzME1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQzMl8xMzAgPSAxMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NmaXhlZDMyXzEzMCA9IDEzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkMzJfMTMwID0gMTMwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXyA9IGZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ZpeGVkNjRfMTMxID0gMTMxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzEoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zZml4ZWQ2NF8xMzEgPSAxMzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50MzJTaW50MzIxMzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTaW50MzIxMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50MzIxMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDMyMTMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJTaW50MzIxMzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8gPSBmaWVsZE1hcFNpbnQzMlNpbnQzMjEzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDMyMTMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQzMl8xMzIgPSAxMzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDMyXzEzMiA9IDEzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJTaW50MzIxMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50MzIxMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50MzJfMTMyID0gMTMyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyU2ludDMyMTMyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDMyMTMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50MzJTaW50NjQxMzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJTaW50NjQxMzNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJTaW50NjQxMzNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDMyU2ludDY0MTMzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50MzJTaW50NjQxMzNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18gPSBmaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDMyU2ludDY0MTMzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3NpbnQ2NF8xMzMgPSAxMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50MzJTaW50NjQxMzNPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTaW50NjQxMzMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl9zaW50NjRfMTMzID0gMTMzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDMyU2ludDY0MTMzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU2ludDY0MTMzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc2ludDY0XzEzMyA9IDEzMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlNpbnQ2NDEzMygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlN0cmluZzEzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlN0cmluZzEzNERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDMyU3RyaW5nMTM0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfID0gZmllbGRNYXBTaW50MzJTdHJpbmcxMzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQzMlN0cmluZzEzNF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50MzJfc3RyaW5nXzEzNCA9IDEzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlN0cmluZzEzNCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDMyX3N0cmluZ18xMzQgPSAxMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJTdHJpbmcxMzQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQzMl9zdHJpbmdfMTM0ID0gMTM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyU3RyaW5nMTM0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJTdHJpbmcxMzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJVaW50MzIxMzVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50MzIxMzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlVpbnQzMjEzNV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDMyMTM1XyA9IGZpZWxkTWFwU2ludDMyVWludDMyMTM1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJVaW50MzIxMzVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyVWludDMyMTM1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDMyMTM1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDMyXzEzNSA9IDEzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50MzJfMTM1ID0gMTM1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDMyMTM1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJVaW50MzIxMzUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQzMjEzNSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQzMl8xMzUgPSAxMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50MzJVaW50MzIxMzUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50MzIxMzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50MzJVaW50NjQxMzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50MzJVaW50NjQxMzZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDMyVWludDY0MTM2XyA9IGZpZWxkTWFwU2ludDMyVWludDY0MTM2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50MzJVaW50NjQxMzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDMyVWludDY0MTM2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50MzJfdWludDY0XzEzNiA9IDEzNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDMyX3VpbnQ2NF8xMzYgPSAxMzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50MzJVaW50NjQxMzYoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50MzJVaW50NjQxMzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQzMl91aW50NjRfMTM2ID0gMTM2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDMyVWludDY0MTM2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDMyVWludDY0MTM2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTaW50NjRCb29sMTM3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCb29sMTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEJvb2wxMzdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Qm9vbDEzN18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRCb29sMTM3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRCb29sMTM3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRCb29sMTM3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRCb29sMTM3XyA9IGZpZWxkTWFwU2ludDY0Qm9vbDEzN18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qm9vbDEzN187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzdPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Qm9vbDEzNygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3NpbnQ2NF9ib29sXzEzNyA9IDEzNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwU2ludDY0Qm9vbDEzN09yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYm9vbF8xMzcgPSAxMzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRCb29sMTM3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCb29sMTM3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfc2ludDY0X2Jvb2xfMTM3ID0gMTM3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0Qm9vbDEzNygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJvb2wxMzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZmllbGRNYXBTaW50NjRCeXRlczEzOF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRCeXRlczEzOF8gPSBmaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRCeXRlczEzOF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBTaW50NjRCeXRlczEzOE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc2ludDY0X2J5dGVzXzEzOCA9IDEzODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRCeXRlczEzOCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4ID0gMTM4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Qnl0ZXMxMzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjREb3VibGUxMzlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjREb3VibGUxMzlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjREb3VibGUxMzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NERvdWJsZTEzOV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0RG91YmxlMTM5XyA9IGZpZWxkTWFwU2ludDY0RG91YmxlMTM5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjREb3VibGUxMzlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTaW50NjREb3VibGUxMzlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwU2ludDY0RG91YmxlMTM5T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjREb3VibGUxMzkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjREb3VibGUxMzkoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RG91YmxlMTM5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZG91YmxlXzEzOSA9IDEzOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZG91YmxlJmd0OyBmaWVsZF9tYXBfc2ludDY0X2RvdWJsZV8xMzkgPSAxMzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjREb3VibGUxMzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NERvdWJsZTEzOSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0RW51bTE0MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRFbnVtMTQwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRFbnVtMTQwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEVudW0xNDBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0RW51bTE0MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0RW51bTE0MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0RW51bTE0MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0RW51bTE0MF8gPSBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEVudW0xNDBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEVudW0xNDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU2ludDY0RW51bTE0ME1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFNpbnQ2NEVudW0xNDBWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3NpbnQ2NF9lbnVtXzE0MCA9IDE0MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWVPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0RW51bTE0MCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0RW51bTE0MCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRFbnVtMTQwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFNpbnQ2NEVudW0xNDBNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEVudW0xNDAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zaW50NjRfZW51bV8xNDAgPSAxNDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRFbnVtMTQwVmFsdWUoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRFbnVtMTQwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc2ludDY0X2VudW1fMTQwID0gMTQwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0RW51bTE0MFZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RW51bTE0MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDMyMTQxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MV8gPSBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDMyXzE0MSA9IDE0MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGaXhlZDMyMTQxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkMzJfMTQxID0gMTQxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJfID0gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGaXhlZDY0MTQyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ZpeGVkNjRfMTQyID0gMTQyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9maXhlZDY0XzE0MiA9IDE0Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZml4ZWQ2NF8xNDIgPSAxNDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRGbG9hdDE0M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRGbG9hdDE0M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0RmxvYXQxNDNfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXyA9IGZpZWxkTWFwU2ludDY0RmxvYXQxNDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NEZsb2F0MTQzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRGbG9hdDE0M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRGbG9hdDE0MygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRGbG9hdDE0MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfZmxvYXRfMTQzID0gMTQzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3NpbnQ2NF9mbG9hdF8xNDMgPSAxNDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRGbG9hdDE0MygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0RmxvYXQxNDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2Zsb2F0XzE0MyA9IDE0Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEZsb2F0MTQzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRJbnQzMjE0NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQzMjE0NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRJbnQzMjE0NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDMyMTQ0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRJbnQzMjE0NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfID0gZmllbGRNYXBTaW50NjRJbnQzMjE0NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50MzIxNDRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0SW50MzIxNDRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50MzJfMTQ0ID0gMTQ0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQzMjE0NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDMyXzE0NCA9IDE0NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQzMjE0NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50MzIxNDQoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQzMl8xNDQgPSAxNDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRJbnQzMjE0NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDMyMTQ0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRJbnQ2NDE0NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfID0gZmllbGRNYXBTaW50NjRJbnQ2NDE0NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0SW50NjQxNDVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0SW50NjQxNDVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRJbnQ2NDE0NU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X2ludDY0XzE0NSA9IDE0NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0SW50NjQxNDUoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NEludDY0MTQ1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9pbnQ2NF8xNDUgPSAxNDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRJbnQ2NDE0NSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfaW50NjRfMTQ1ID0gMTQ1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0SW50NjQxNDUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRJbnQ2NDE0NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkNvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPiBmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZ2V0RmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDZPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0Nk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3NpbnQ2NF9tZXNzYWdlXzE0NiA9IDE0Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NE1lc3NhZ2UxNDYoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc2ludDY0X21lc3NhZ2VfMTQ2ID0gMTQ2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zaW50NjRfbWVzc2FnZV8xNDYgPSAxNDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N18gPSBmaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQzMl8xNDcgPSAxNDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkMzJfMTQ3ID0gMTQ3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0NygpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDMyXzE0NyA9IDE0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF8gPSBmaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ZpeGVkNjRfMTQ4ID0gMTQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NmaXhlZDY0XzE0OCA9IDE0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zZml4ZWQ2NF8xNDggPSAxNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBTaW50NjRTaW50MzIxNDlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50MzIxNDlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50MzIxNDlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTaW50NjRTaW50MzIxNDlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8gPSBmaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U2ludDMyMTQ5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU2ludDY0U2ludDMyMTQ5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50MzJfMTQ5ID0gMTQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDMyMTQ5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDMyXzE0OSA9IDE0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQzMl8xNDkgPSAxNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTaW50MzIxNDkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50MzIxNDkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTaW50NjQxNTBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTaW50NjQxNTBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXyA9IGZpZWxkTWFwU2ludDY0U2ludDY0MTUwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTaW50NjQxNTBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRTaW50NjQxNTBPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc2ludDY0XzE1MCA9IDE1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U2ludDY0MTUwKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF9zaW50NjRfMTUwID0gMTUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0U2ludDY0MTUwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3NpbnQ2NF8xNTAgPSAxNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTaW50NjRTaW50NjQxNTAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTaW50NjQxNTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRTdHJpbmcxNTFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFN0cmluZzE1MV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXyA9IGZpZWxkTWFwU2ludDY0U3RyaW5nMTUxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRTdHJpbmcxNTFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNTEgPSAxNTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zaW50NjRfc3RyaW5nXzE1MSA9IDE1MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFNpbnQ2NFN0cmluZzE1MSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3NpbnQ2NF9zdHJpbmdfMTUxID0gMTUxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU2ludDY0U3RyaW5nMTUxKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRTdHJpbmcxNTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTaW50NjRVaW50MzIxNTJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTaW50NjRVaW50MzIxNTJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU2ludDY0VWludDMyMTUyXyA9IGZpZWxkTWFwU2ludDY0VWludDMyMTUyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTaW50NjRVaW50MzIxNTJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTaW50NjRVaW50MzIxNTJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQzMl8xNTIgPSAxNTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50MzIxNTIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyID0gMTUyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU2ludDY0VWludDMyMTUyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDMyMTUyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDMyXzE1MiA9IDE1Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU2ludDY0VWludDY0MTUzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU2ludDY0VWludDY0MTUzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU2ludDY0VWludDY0MTUzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU2ludDY0VWludDY0MTUzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTaW50NjRVaW50NjQxNTNfID0gZmllbGRNYXBTaW50NjRVaW50NjQxNTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU2ludDY0VWludDY0MTUzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3NpbnQ2NF91aW50NjRfMTUzID0gMTUzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTaW50NjRVaW50NjQxNTMoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfc2ludDY0X3VpbnQ2NF8xNTMgPSAxNTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTaW50NjRVaW50NjQxNTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU2ludDY0VWludDY0MTUzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1MyA9IDE1Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBTdHJpbmdCb29sMTU0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Jvb2wxNTREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQm9vbDE1NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nQm9vbDE1NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nQm9vbDE1NF8gPSBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Jvb2wxNTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nQm9vbDE1NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBTdHJpbmdCb29sMTU0T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdCb29sMTU0KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYm9vbF8xNTQgPSAxNTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdCb29sMTU0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgZmllbGRfbWFwX3N0cmluZ19ib29sXzE1NCA9IDE1NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0Jvb2wxNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCb29sMTU0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0ID0gMTU0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nQm9vbDE1NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQm9vbDE1NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdCeXRlczE1NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XyA9IGZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0J5dGVzMTU1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfYnl0ZXNfMTU1ID0gMTU1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFN0cmluZ0J5dGVzMTU1T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkgewogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdCeXRlczE1NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgZmllbGRfbWFwX3N0cmluZ19ieXRlc18xNTUgPSAxNTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdCeXRlczE1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NSA9IDE1NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0J5dGVzMTU1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdEb3VibGUxNTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2XyA9IGZpZWxkTWFwU3RyaW5nRG91YmxlMTU2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdEb3VibGUxNTZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nRG91YmxlMTU2TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZG91YmxlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2RvdWJsZV8xNTYgPSAxNTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1Nk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGRvdWJsZSZndDsgZmllbGRfbWFwX3N0cmluZ19kb3VibGVfMTU2ID0gMTU2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigpIHsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRG91YmxlMTU2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZG91YmxlXzE1NiA9IDE1Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0RvdWJsZTE1NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdEb3VibGUxNTYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nRW51bTE1N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0VudW0xNTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdFbnVtMTU3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0VudW0xNTdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdFbnVtMTU3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0VudW0xNTdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0VudW0xNTdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0VudW0xNTdfID0gZmllbGRNYXBTdHJpbmdFbnVtMTU3Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdFbnVtMTU3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFN0cmluZ0VudW0xNTdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBTdHJpbmdFbnVtMTU3VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRW51bTE1NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0VudW0xNTdWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRW51bTE1NygpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRW51bTE1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBTdHJpbmdFbnVtMTU3TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3N0cmluZ19lbnVtXzE1NyA9IDE1Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0VudW0xNTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0VudW0xNTcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZW51bV8xNTcgPSAxNTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdFbnVtMTU3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwU3RyaW5nRW51bTE1N01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2VudW1fMTU3ID0gMTU3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nRW51bTE1N1ZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdFbnVtMTU3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4XyA9IGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQzMl8xNTggPSAxNTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKSB7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkMzJfMTU4ID0gMTU4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDMyXzE1OCA9IDE1ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlfID0gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ZpeGVkNjRfMTU5ID0gMTU5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKSB7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZml4ZWQ2NF8xNTkgPSAxNTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdGaXhlZDY0MTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19maXhlZDY0XzE1OSA9IDE1OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nRmxvYXQxNjBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdGbG9hdDE2MF8gPSBmaWVsZE1hcFN0cmluZ0Zsb2F0MTYwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdGbG9hdDE2MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBmbG9hdCZndDsgZmllbGRfbWFwX3N0cmluZ19mbG9hdF8xNjAgPSAxNjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBTdHJpbmdGbG9hdDE2ME9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpIHsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKCkgewogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdGbG9hdDE2MCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgZmxvYXQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfZmxvYXRfMTYwID0gMTYwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2Zsb2F0XzE2MCA9IDE2MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ0Zsb2F0MTYwKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nRmxvYXQxNjAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50MzIxNjFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdJbnQzMjE2MURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50MzIxNjFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ0ludDMyMTYxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdJbnQzMjE2MV8gPSBmaWVsZE1hcFN0cmluZ0ludDMyMTYxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdJbnQzMjE2MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjFPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQzMl8xNjEgPSAxNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50MzIxNjEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzE2MSA9IDE2MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ0ludDMyMTYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQzMjE2MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50MzJfMTYxID0gMTYxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nSW50MzIxNjEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDMyMTYxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ0ludDY0MTYyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ0ludDY0MTYyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nSW50NjQxNjJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ0ludDY0MTYyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfID0gZmllbGRNYXBTdHJpbmdJbnQ2NDE2Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nSW50NjQxNjJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ0ludDY0MTYyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdJbnQ2NDE2Mk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX2ludDY0XzE2MiA9IDE2Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjJPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyID0gMTYyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ0ludDY0MTYyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19pbnQ2NF8xNjIgPSAxNjI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdJbnQ2NDE2MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nSW50NjQxNjIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNDb252ZXJ0ZXIgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyID0gbmV3IEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfbWVzc2FnZV8xNjMgPSAxNjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2M0NvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfc3RyaW5nX21lc3NhZ2VfMTYzID0gMTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjMoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2MyA9IDE2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nTWVzc2FnZTE2MygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfID0gZmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkMzJfMTY0ID0gMTY0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjQgPSAxNjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDMyXzE2NCA9IDE2NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XyA9IGZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zZml4ZWQ2NF8xNjUgPSAxNjU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NSA9IDE2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ZpeGVkNjRfMTY1ID0gMTY1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTaW50MzIxNjZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8gPSBmaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDMyMTY2XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50MzJfMTY2ID0gMTY2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQzMl8xNjYgPSAxNjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTaW50MzIxNjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NiA9IDE2Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDMyMTY2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBTdHJpbmdTaW50NjQxNjdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18gPSBmaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU2ludDY0MTY3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ19zaW50NjRfMTY3ID0gMTY3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdTaW50NjQxNjdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU2ludDY0MTY3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc2ludDY0XzE2NyA9IDE2Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc2ludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjcgPSAxNjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBTdHJpbmdTaW50NjQxNjcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFN0cmluZ1N0cmluZzE2OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfID0gZmllbGRNYXBTdHJpbmdTdHJpbmcxNjhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFN0cmluZ1N0cmluZzE2OF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFN0cmluZ1N0cmluZzE2OE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBTdHJpbmdTdHJpbmcxNjhPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3N0cmluZ18xNjggPSAxNjg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4ID0gMTY4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfc3RyaW5nXzE2OCA9IDE2ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdTdHJpbmcxNjgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50MzIxNjlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1VpbnQzMjE2OV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDMyMTY5XyA9IGZpZWxkTWFwU3RyaW5nVWludDMyMTY5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50MzIxNjlfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQzMl8xNjkgPSAxNjk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OSA9IDE2OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDMyMTY5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZmllbGRfbWFwX3N0cmluZ191aW50MzJfMTY5ID0gMTY5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwU3RyaW5nVWludDMyMTY5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50MzIxNjkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBTdHJpbmdVaW50NjQxNzBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXyA9IGZpZWxkTWFwU3RyaW5nVWludDY0MTcwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBTdHJpbmdVaW50NjQxNzBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDY0Jmd0OyBmaWVsZF9tYXBfc3RyaW5nX3VpbnQ2NF8xNzAgPSAxNzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3ME9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBTdHJpbmdVaW50NjQxNzAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3N0cmluZ191aW50NjRfMTcwID0gMTcwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwU3RyaW5nVWludDY0MTcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF9zdHJpbmdfdWludDY0XzE3MCA9IDE3MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwU3RyaW5nVWludDY0MTcwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gZmllbGRNYXBVaW50MzJCb29sMTcxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkJvb2wxNzFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkJvb2wxNzFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQm9vbDE3MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJCb29sMTcxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJCb29sMTcxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJCb29sMTcxXyA9IGZpZWxkTWFwVWludDMyQm9vbDE3MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQm9vbDE3MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyQm9vbDE3MSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJCb29sMTcxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDMyQm9vbDE3MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzFPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJCb29sMTcxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJvb2wxNzEoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50MzJfYm9vbF8xNzEgPSAxNzE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJCb29sMTcxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQm9vbDE3MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQzMl9ib29sXzE3MSA9IDE3MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkJvb2wxNzEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCb29sMTcxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJCeXRlczE3Ml8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkJ5dGVzMTcyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJCeXRlczE3Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfID0gZmllbGRNYXBVaW50MzJCeXRlczE3Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyQnl0ZXMxNzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGJ5dGVzJmd0OyBmaWVsZF9tYXBfdWludDMyX2J5dGVzXzE3MiA9IDE3Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJCeXRlczE3Mk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDMyQnl0ZXMxNzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50MzJfYnl0ZXNfMTcyID0gMTcyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyQnl0ZXMxNzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkJ5dGVzMTcyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQzMl9ieXRlc18xNzIgPSAxNzI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJCeXRlczE3MigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJCeXRlczE3MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRG91YmxlMTczKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRG91YmxlMTczXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJEb3VibGUxNzNfID0gZmllbGRNYXBVaW50MzJEb3VibGUxNzNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkRvdWJsZTE3M187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfZG91YmxlXzE3MyA9IDE3Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRG91YmxlMTczKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldEZpZWxkTWFwVWludDMyRG91YmxlMTczT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQzMl9kb3VibGVfMTczID0gMTczOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRG91YmxlMTczKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJEb3VibGUxNzMoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZG91YmxlJmd0OyBmaWVsZF9tYXBfdWludDMyX2RvdWJsZV8xNzMgPSAxNzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJEb3VibGUxNzMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyRW51bTE3NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJFbnVtMTc0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJFbnVtMTc0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkVudW0xNzRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRW51bTE3NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRW51bTE3NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRW51bTE3NF8gPSBmaWVsZE1hcFVpbnQzMkVudW0xNzRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkVudW0xNzRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50MzJFbnVtMTc0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBmaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50MzJfZW51bV8xNzQgPSAxNzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRW51bTE3NFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRGaWVsZE1hcFVpbnQzMkVudW0xNzRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDMyX2VudW1fMTc0ID0gMTc0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyRW51bTE3NCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBVaW50MzJFbnVtMTc0VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkVudW0xNzQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDMyRW51bTE3NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJFbnVtMTc0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRW51bTE3NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQzMl9lbnVtXzE3NCA9IDE3NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkVudW0xNzRWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkVudW0xNzQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyRml4ZWQzMjE3NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVfID0gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDMyMTc1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJGaXhlZDMyMTc1TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkMzJfMTc1ID0gMTc1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9maXhlZDMyXzE3NSA9IDE3NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzUgPSAxNzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGaXhlZDY0MTc2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nl8gPSBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ZpeGVkNjRfMTc2ID0gMTc2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZpeGVkNjQxNzYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzYgPSAxNzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyRmxvYXQxNzdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJGbG9hdDE3N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJGbG9hdDE3N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyRmxvYXQxNzdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XyA9IGZpZWxkTWFwVWludDMyRmxvYXQxNzdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkZsb2F0MTc3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDMyRmxvYXQxNzdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50MzJGbG9hdDE3N09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3ID0gMTc3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyRmxvYXQxNzcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2Zsb2F0XzE3NyA9IDE3Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkZsb2F0MTc3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQzMl9mbG9hdF8xNzcgPSAxNzc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJGbG9hdDE3NygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJGbG9hdDE3NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMySW50MzIxNzhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50MzIxNzhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMySW50MzIxNzhfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJJbnQzMjE3OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMySW50MzIxNzhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMkludDMyMTc4XyA9IGZpZWxkTWFwVWludDMySW50MzIxNzhfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDMyMTc4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMySW50MzIxNzhDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMySW50MzIxNzgoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMySW50MzIxNzhNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50MzJfMTc4ID0gMTc4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDMyMTc4T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQzMjE3OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDMyMTc4KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzggPSAxNzg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJJbnQzMjE3OCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDMyXzE3OCA9IDE3ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMkludDMyMTc4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50MzIxNzgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMkludDY0MTc5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMkludDY0MTc5XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMySW50NjQxNzlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMkludDY0MTc5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJJbnQ2NDE3OV8gPSBmaWVsZE1hcFVpbnQzMkludDY0MTc5Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJJbnQ2NDE3OV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMkludDY0MTc5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX2ludDY0XzE3OSA9IDE3OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMySW50NjQxNzlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50MzJJbnQ2NDE3OU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMySW50NjQxNzkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMkludDY0MTc5KCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfaW50NjRfMTc5ID0gMTc5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMySW50NjQxNzkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJJbnQ2NDE3OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlciA9IG5ldyBGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPiBmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDMyTWVzc2FnZTE4ME9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGZpZWxkTWFwVWludDMyTWVzc2FnZTE4MENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBnZXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJNZXNzYWdlMTgwQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwODAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50MzJfbWVzc2FnZV8xODAgPSAxODA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQzMl9tZXNzYWdlXzE4MCA9IDE4MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyTWVzc2FnZTE4MCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDMyX21lc3NhZ2VfMTgwID0gMTgwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJNZXNzYWdlMTgwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIHsKICAgICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV8gPSBmaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDMyXzE4MSA9IDE4MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ZpeGVkMzJfMTgxID0gMTgxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODEoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQzMl8xODEgPSAxODE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfID0gZmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zZml4ZWQ2NF8xODIgPSAxODI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NmaXhlZDY0XzE4MiA9IDE4Mjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTaW50MzIxODNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50MzIxODNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlNpbnQzMjE4M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDMyMTgzXyA9IGZpZWxkTWFwVWludDMyU2ludDMyMTgzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTaW50MzIxODNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ludDMyMTgzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDMyMTgzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDMyXzE4MyA9IDE4Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJTaW50MzIxODNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50MzJfMTgzID0gMTgzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlNpbnQzMjE4M09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJTaW50MzIxODMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDMyMTgzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTaW50MzIxODMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQzMjE4MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQzMl8xODMgPSAxODM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJTaW50MzIxODMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50MzIxODMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50MzJTaW50NjQxODRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50MzJTaW50NjQxODREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDMyU2ludDY0MTg0XyA9IGZpZWxkTWFwVWludDMyU2ludDY0MTg0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50MzJTaW50NjQxODRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDMyU2ludDY0MTg0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfc2ludDY0XzE4NCA9IDE4NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJTaW50NjQxODRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJTaW50NjQxODQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3NpbnQ2NF8xODQgPSAxODQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50MzJTaW50NjQxODQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTaW50NjQxODQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl9zaW50NjRfMTg0ID0gMTg0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDMyU2ludDY0MTg0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU2ludDY0MTg0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyU3RyaW5nMTg1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50MzJTdHJpbmcxODVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8gPSBmaWVsZE1hcFVpbnQzMlN0cmluZzE4NV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDMyU3RyaW5nMTg1XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQzMl9zdHJpbmdfMTg1ID0gMTg1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50MzJTdHJpbmcxODVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50MzJTdHJpbmcxODUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyU3RyaW5nMTg1KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50MzJfc3RyaW5nXzE4NSA9IDE4NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDMyX3N0cmluZ18xODUgPSAxODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJTdHJpbmcxODUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlN0cmluZzE4NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDMyVWludDMyMTg2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyVWludDMyMTg2XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDMyMTg2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50MzIxODZfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyVWludDMyMTg2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50MzIxODZfID0gZmllbGRNYXBVaW50MzJVaW50MzIxODZfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJVaW50MzIxODYoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50MzJfMTg2ID0gMTg2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4Nk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50MzJVaW50MzIxODZPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQzMl8xODYgPSAxODY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDMyVWludDMyMTg2T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJVaW50MzIxODYoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50MzIxODYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDMyMTg2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDMyXzE4NiA9IDE4Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQzMjE4NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDMyVWludDY0MTg3XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDMyVWludDY0MTg3XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDMyVWludDY0MTg3RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDMyVWludDY0MTg3Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50MzJVaW50NjQxODdfID0gZmllbGRNYXBVaW50MzJVaW50NjQxODdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQzMl91aW50NjRfMTg3ID0gMTg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDMyVWludDY0MTg3T3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50MzJVaW50NjQxODcoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDMyVWludDY0MTg3KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50MzJfdWludDY0XzE4NyA9IDE4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQzMlVpbnQ2NDE4NygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDMyX3VpbnQ2NF8xODcgPSAxODc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50MzJVaW50NjQxODcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50MzJVaW50NjQxODcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qm9vbDE4OF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Qm9vbDE4OF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRCb29sMTg4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEJvb2wxODhEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEJvb2wxODhfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJvb2wxODhfID0gZmllbGRNYXBVaW50NjRCb29sMTg4Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCb29sMTg4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRCb29sMTg4KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpZWxkTWFwVWludDY0Qm9vbDE4OE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRCb29sMTg4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBib29sJmd0OyBmaWVsZF9tYXBfdWludDY0X2Jvb2xfMTg4ID0gMTg4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RmllbGRNYXBVaW50NjRCb29sMTg4T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYm9vbCZndDsgZmllbGRfbWFwX3VpbnQ2NF9ib29sXzE4OCA9IDE4ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRCb29sMTg4KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJvb2wxODgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGJvb2wmZ3Q7IGZpZWxkX21hcF91aW50NjRfYm9vbF8xODggPSAxODg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRCb29sMTg4KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qm9vbDE4OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRCeXRlczE4OV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRCeXRlczE4OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0Qnl0ZXMxODlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XyA9IGZpZWxkTWFwVWludDY0Qnl0ZXMxODlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRCeXRlczE4OU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRCeXRlczE4OSgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgYnl0ZXMmZ3Q7IGZpZWxkX21hcF91aW50NjRfYnl0ZXNfMTg5ID0gMTg5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Qnl0ZXMxODkoKSB7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRCeXRlczE4OSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBieXRlcyZndDsgZmllbGRfbWFwX3VpbnQ2NF9ieXRlc18xODkgPSAxODk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRCeXRlczE4OSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRCeXRlczE4OSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjREb3VibGUxOTBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0RG91YmxlMTkwXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjREb3VibGUxOTBfID0gZmllbGRNYXBVaW50NjREb3VibGUxOTBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NERvdWJsZTE5MF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjREb3VibGUxOTAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTAoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IGdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5ME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RmllbGRNYXBVaW50NjREb3VibGUxOTBPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgpIHsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjREb3VibGUxOTAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGRvdWJsZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9kb3VibGVfMTkwID0gMTkwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0RG91YmxlMTkwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBkb3VibGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MCA9IDE5MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NERvdWJsZTE5MCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RG91YmxlMTkwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRFbnVtMTkxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEVudW0xOTFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRFbnVtMTkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEVudW0xOTFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RW51bTE5MV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRFbnVtMTkxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRFbnVtMTkxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRFbnVtMTkxXyA9IGZpZWxkTWFwVWludDY0RW51bTE5MV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RW51bTE5MV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0RW51bTE5MSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bT4KICAgICAgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+CiAgICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRmllbGRNYXBVaW50NjRFbnVtMTkxTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtIGdldEZpZWxkTWFwVWludDY0RW51bTE5MU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEZpZWxkTWFwVWludDY0RW51bTE5MVZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtJmd0OyBmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxID0gMTkxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZU9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRFbnVtMTkxKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRFbnVtMTkxKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEVudW0xOTEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEZpZWxkTWFwVWludDY0RW51bTE5MU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RW51bTE5MSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSZndDsgZmllbGRfbWFwX3VpbnQ2NF9lbnVtXzE5MSA9IDE5MTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEVudW0xOTFWYWx1ZSgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEVudW0xOTEoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0mZ3Q7IGZpZWxkX21hcF91aW50NjRfZW51bV8xOTEgPSAxOTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRFbnVtMTkxVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRFbnVtMTkxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRGaXhlZDMyMTkyXyA9IGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Ml87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5Mk9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkgewogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyID0gMTkyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQzMl8xOTIgPSAxOTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRGaXhlZDMyMTkyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRGaXhlZDY0MTkzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M18gPSBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZml4ZWQ2NF8xOTMgPSAxOTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzID0gMTkzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0Rml4ZWQ2NDE5MygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9maXhlZDY0XzE5MyA9IDE5Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRGbG9hdDE5NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEZsb2F0MTk0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRGbG9hdDE5NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfID0gZmllbGRNYXBVaW50NjRGbG9hdDE5NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0RmxvYXQxOTRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkZsb2F0PiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IGdldEZpZWxkTWFwVWludDY0RmxvYXQxOTRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBmbG9hdCZndDsgZmllbGRfbWFwX3VpbnQ2NF9mbG9hdF8xOTQgPSAxOTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGZsb2F0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2Zsb2F0XzE5NCA9IDE5NDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEZsb2F0MTk0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBmbG9hdCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRGbG9hdDE5NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgZmxvYXQmZ3Q7IGZpZWxkX21hcF91aW50NjRfZmxvYXRfMTk0ID0gMTk0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0RmxvYXQxOTQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0RmxvYXQxOTQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NEludDMyMTk1XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDMyMTk1RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDMyMTk1XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50MzIxOTVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEludDMyMTk1Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQzMjE5NV8gPSBmaWVsZE1hcFVpbnQ2NEludDMyMTk1Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQzMjE5NV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQzMl8xOTUgPSAxOTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0SW50MzIxOTVPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50MzJfMTk1ID0gMTk1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0SW50MzIxOTUoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDMyMTk1KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQzMjE5NSgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDMyXzE5NSA9IDE5NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NEludDMyMTk1KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50MzIxOTUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NEludDY0MTk2RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NEludDY0MTk2XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0SW50NjQxOTZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NEludDY0MTk2Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl8gPSBmaWVsZE1hcFVpbnQ2NEludDY0MTk2Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRJbnQ2NDE5Nl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5Nk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0SW50NjQxOTZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfaW50NjRfMTk2ID0gMTk2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0SW50NjQxOTYoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRJbnQ2NDE5NigpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0SW50NjQxOTYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIGludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X2ludDY0XzE5NiA9IDE5Njs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NEludDY0MTk2KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9pbnQ2NF8xOTYgPSAxOTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRJbnQ2NDE5NigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NEludDY0MTk2KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3Q29udmVydGVyID0gbmV3IEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+IGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRNZXNzYWdlMTk3XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+IGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiBnZXRGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGdldEZpZWxkTWFwVWludDY0TWVzc2FnZTE5N09yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUgZ2V0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTdDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGU+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlJmd0OyBmaWVsZF9tYXBfdWludDY0X21lc3NhZ2VfMTk3ID0gMTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0TWVzc2FnZTE5NygKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUmZ3Q7IGZpZWxkX21hcF91aW50NjRfbWVzc2FnZV8xOTcgPSAxOTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSZndDsgZmllbGRfbWFwX3VpbnQ2NF9tZXNzYWdlXzE5NyA9IDE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRNZXNzYWdlMTk3QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NE1lc3NhZ2UxOTcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuUHJvdG8zVGVzdGluZ0xpdGUuUHJvdG8zTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgewogICAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XyA9IGZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDMyXzE5OCA9IDE5ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQzMl8xOTggPSAxOTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkMzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkMzJfMTk4ID0gMTk4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOTgoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XyA9IGZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzZml4ZWQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zZml4ZWQ2NF8xOTkgPSAxOTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ZpeGVkNjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ZpeGVkNjRfMTk5ID0gMTk5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNmaXhlZDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NmaXhlZDY0XzE5OSA9IDE5OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRTaW50MzIyMDBfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRTaW50MzIyMDBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGZpZWxkTWFwVWludDY0U2ludDMyMjAwXyA9IGZpZWxkTWFwVWludDY0U2ludDMyMjAwXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTaW50MzIyMDBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ZpZWxkTWFwVWludDY0U2ludDMyMjAwKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpIHsKICAgICAgICByZXR1cm4gZ2V0RmllbGRNYXBVaW50NjRTaW50MzIyMDBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwME9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQzMl8yMDAgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50MzIyMDAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50MzJfMjAwID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U2ludDMyMjAwKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDMyMjAwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDMyXzIwMCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGZpZWxkTWFwVWludDY0U2ludDY0MjAxXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0U2ludDY0MjAxXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0U2ludDY0MjAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U2ludDY0MjAxXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTaW50NjQyMDFfID0gZmllbGRNYXBVaW50NjRTaW50NjQyMDFfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U2ludDY0MjAxTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldEZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMU9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHNpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF9zaW50NjRfMjAxID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDFPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTaW50NjQyMDEoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc2ludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3NpbnQ2NF8yMDEgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRTaW50NjQyMDEoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U2ludDY0MjAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzaW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfc2ludDY0XzIwMSA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0U3RyaW5nMjAyXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfID0gZmllbGRNYXBVaW50NjRTdHJpbmcyMDJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFN0cmluZzIwMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCBzdHJpbmcmZ3Q7IGZpZWxkX21hcF91aW50NjRfc3RyaW5nXzIwMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRNYXBVaW50NjRTdHJpbmcyMDJPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFwVWludDY0U3RyaW5nMjAyKCkgewogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHN0cmluZyZndDsgZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMjAyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEZpZWxkTWFwVWludDY0U3RyaW5nMjAyKAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgc3RyaW5nJmd0OyBmaWVsZF9tYXBfdWludDY0X3N0cmluZ18yMDIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmllbGRNYXBVaW50NjRTdHJpbmcyMDIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFN0cmluZzIwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGZpZWxkTWFwVWludDY0VWludDMyMjAzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDMyMjAzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDMyMjAzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIGlmIChmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM18gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpZWxkTWFwVWludDY0VWludDMyMjAzXy5pc011dGFibGUoKSkgewogICAgICAgICAgZmllbGRNYXBVaW50NjRVaW50MzIyMDNfID0gZmllbGRNYXBVaW50NjRVaW50MzIyMDNfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFwVWludDY0VWludDMyMjAzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkgewogICAgICAgIHJldHVybiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDMyMjAzT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDNPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50MzImZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDMyXzIwMyA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKSB7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQzMjIwMygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDMyJmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQzMl8yMDMgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RmllbGRNYXBVaW50NjRVaW50MzIyMDMoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50MzIyMDMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQzMiZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50MzJfMjAzID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0VWludDMyMjAzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDMyMjAzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZmllbGRNYXBVaW50NjRVaW50NjQyMDRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBpZiAoZmllbGRNYXBVaW50NjRVaW50NjQyMDRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRmllbGRNYXBVaW50NjRVaW50NjQyMDREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgaWYgKGZpZWxkTWFwVWludDY0VWludDY0MjA0XyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEZpZWxkTWFwVWludDY0VWludDY0MjA0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmllbGRNYXBVaW50NjRVaW50NjQyMDRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8gPSBmaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFwVWludDY0VWludDY0MjA0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0RmllbGRNYXBVaW50NjRVaW50NjQyMDQoKSB7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldEZpZWxkTWFwVWludDY0VWludDY0MjA0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDQgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgpIHsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IGZpZWxkX21hcF91aW50NjRfdWludDY0XzIwNCA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXBVaW50NjRVaW50NjQyMDQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgZmllbGRfbWFwX3VpbnQ2NF91aW50NjRfMjA0ID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFwVWludDY0VWludDY0MjA0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFwVWludDY0VWludDY0MjA0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5Qcm90bzNUZXN0aW5nTGl0ZS5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLlByb3RvM1Rlc3RpbmdMaXRlLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5TGl0ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sQm9vbDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbERvdWJsZTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRW51bTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDMyNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQzMjEzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDMyMTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sU2ludDY0MTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQzMjE2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDMyMTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sVWludDY0MTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJFbnVtMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRmxvYXQyNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQzMjI1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMySW50NjQyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJNZXNzYWdlMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ZpeGVkNjQyOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU2ludDMyMzBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyU3RyaW5nMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyVWludDMyMzNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qnl0ZXMzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGaXhlZDMyMzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0VWludDY0NTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkJ5dGVzNTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRG91YmxlNTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRG91YmxlNTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkVudW01NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkMzI1NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZpeGVkNjQ1N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkZsb2F0NThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkludDY0NjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMk1lc3NhZ2U2MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNmaXhlZDMyNjJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50MzI2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50MzI2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ludDY0NjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyVWludDY0NjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJvb2w2OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RG91YmxlNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEVudW03MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkMzI3M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZpeGVkNjQ3NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEZsb2F0NzVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NEludDY0NzdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0VWludDY0ODVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJvb2w4NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRG91YmxlODhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkVudW04OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZpeGVkNjQ5MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkZsb2F0OTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50MzI5M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkludDY0OTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlN0cmluZzEwMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQm9vbDEyMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCeXRlczEyMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRW51bTEyM0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRW51bTEyM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZpeGVkMzIxMjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDY0MTI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDMyMTM1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDY0MTM2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRFbnVtMTQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkNjQxNDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQzMjE0NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQ2NDE0NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRNZXNzYWdlMTQ2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDMyMTUyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0VudW0xNTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGaXhlZDMyMTU4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQm9vbDE3MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCeXRlczE3MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZpeGVkMzIxNzVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDY0MTc2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyTWVzc2FnZTE4MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDMyMTgzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDY0MTg0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDMyMTg2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCb29sMTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RG91YmxlMTkwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRFbnVtMTkxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Rml4ZWQzMjE5MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQ2NDE5NkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRNZXNzYWdlMTk3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDMyMjAwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDMyMjAzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4tY29tL2dvb2dsZS9wcm90b2J1Zi9wcm90bzNfbWVzc2FnZV9saXQiICsKICAgICAgImUucHJvdG9cMDIyXDAyNXByb3RvYnVmLmV4cGVyaW1lbnRhbFwiXDI1NlwwMjJcblwwMjFQcm90byIgKwogICAgICAiM01lc3NhZ2VMaXRlXDAyMlwwMjZcblwwMTZmaWVsZF9kb3VibGVfMVwwMzBcMDAxIFwwMDEoXDAwMVwwMjJcMDI1XG5cciIgKwogICAgICAiZmllbGRfZmxvYXRfMlwwMzBcMDAyIFwwMDEoXDAwMlwwMjJcMDI1XG5ccmZpZWxkX2ludDY0XzNcMDMwXDAwMyBcMDAxIiArCiAgICAgICIoXDAwM1wwMjJcMDI2XG5cMDE2ZmllbGRfdWludDY0XzRcMDMwXDAwNCBcMDAxKFwwMDRcMDIyXDAyNVxuXHJmaWVsZF9pbnQzIiArCiAgICAgICIyXzVcMDMwXDAwNSBcMDAxKFwwMDVcMDIyXDAyN1xuXDAxN2ZpZWxkX2ZpeGVkNjRfNlwwMzBcMDA2IFwwMDEoXDAwNlwwMjJcMDI3XG5cMDE3ZmkiICsKICAgICAgImVsZF9maXhlZDMyXzdcMDMwXDAwNyBcMDAxKFwwMDdcMDIyXDAyNFxuXDAxNGZpZWxkX2Jvb2xfOFwwMzBcMDEwIFwwMDEoIiArCiAgICAgICJcMDEwXDAyMlwwMjZcblwwMTZmaWVsZF9zdHJpbmdfOVwwMzBcdCBcMDAxKFx0XDAyMkJcblwwMjBmaWVsZF9tZXNzYSIgKwogICAgICAiZ2VfMTBcMDMwXG4gXDAwMShcMDEzMigucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3QiICsKICAgICAgIm8zTWVzc2FnZUxpdGVcMDIyXDAyNlxuXDAxNmZpZWxkX2J5dGVzXzExXDAzMFwwMTMgXDAwMShcMDE0XDAyMlwwMjdcbiIgKwogICAgICAiXDAxN2ZpZWxkX3VpbnQzMl8xMlwwMzBcMDE0IFwwMDEoXHJcMDIySFxuXHJmaWVsZF9lbnVtXzEzXDAzMCIgKwogICAgICAiXHIgXDAwMShcMDE2MjEucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZUxpdGUuVGVzdEVudW1cMDIyXDAzMVxuXDAyMWZpZWxkX3NmaXhlZDMyXzE0XDAzMFwwMTYgIiArCiAgICAgICJcMDAxKFwwMTdcMDIyXDAzMVxuXDAyMWZpZWxkX3NmaXhlZDY0XzE1XDAzMFwwMTcgXDAwMShcMDIwXDAyMlwwMjdcblwwMTdmaWVsZF8iICsKICAgICAgInNpbnQzMl8xNlwwMzBcMDIwIFwwMDEoXDAyMVwwMjJcMDI3XG5cMDE3ZmllbGRfc2ludDY0XzE3XDAzMFwwMjEgXDAwMShcMDIyIiArCiAgICAgICJcMDIyIFxuXDAyNGZpZWxkX2RvdWJsZV9saXN0XzE4XDAzMFwwMjIgXDAwMyhcMDAxQlwwMDJcMDIwXDAwMFwwMjJcMDM3XG5cMDIzZmkiICsKICAgICAgImVsZF9mbG9hdF9saXN0XzE5XDAzMFwwMjMgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMFwwMjJcMDM3XG5cMDIzZmllbGRfaW50IiArCiAgICAgICI2NF9saXN0XzIwXDAzMFwwMjQgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMFwwMjIgXG5cMDI0ZmllbGRfdWludDY0X2xpcyIgKwogICAgICAidF8yMVwwMzBcMDI1IFwwMDMoXDAwNEJcMDAyXDAyMFwwMDBcMDIyXDAzN1xuXDAyM2ZpZWxkX2ludDMyX2xpc3RfMjJcMDMwXDAyNiAiICsKICAgICAgIlwwMDMoXDAwNUJcMDAyXDAyMFwwMDBcMDIyIVxuXDAyNWZpZWxkX2ZpeGVkNjRfbGlzdF8yM1wwMzBcMDI3IFwwMDMoXDAwNkJcMDAyIiArCiAgICAgICJcMDIwXDAwMFwwMjIhXG5cMDI1ZmllbGRfZml4ZWQzMl9saXN0XzI0XDAzMFwwMzAgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMFwwMjJcMDM2XG4iICsKICAgICAgIlwwMjJmaWVsZF9ib29sX2xpc3RfMjVcMDMwXDAzMSBcMDAzKFwwMTBCXDAwMlwwMjBcMDAwXDAyMiBcblwwMjRmaWVsZF9zIiArCiAgICAgICJ0cmluZ19saXN0XzI2XDAzMFwwMzIgXDAwMyhcdEJcMDAyXDAyMFwwMDBcMDIyS1xuXDAyNWZpZWxkX21lc3NhZ2UiICsKICAgICAgIl9saXN0XzI3XDAzMFwwMzMgXDAwMyhcMDEzMigucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZUxpdGVCXDAwMlwwMjBcMDAwXDAyMlwwMzdcblwwMjNmaWVsZF9ieXRlc19saXN0IiArCiAgICAgICJfMjhcMDMwXDAzNCBcMDAzKFwwMTRCXDAwMlwwMjBcMDAwXDAyMiBcblwwMjRmaWVsZF91aW50MzJfbGlzdF8yOVwwMzBcMDM1ICIgKwogICAgICAiXDAwMyhcckJcMDAyXDAyMFwwMDBcMDIyUVxuXDAyMmZpZWxkX2VudW1fbGlzdF8zMFwwMzBcMDM2IFwwMDMoXDAxNjIxLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlIiArCiAgICAgICJzdEVudW1CXDAwMlwwMjBcMDAwXDAyMlwiXG5cMDI2ZmllbGRfc2ZpeGVkMzJfbGlzdF8zMVwwMzBcMDM3IFwwMDMiICsKICAgICAgIihcMDE3QlwwMDJcMDIwXDAwMFwwMjJcIlxuXDAyNmZpZWxkX3NmaXhlZDY0X2xpc3RfMzJcMDMwICBcMDAzKFwwMjBCXDAwMiIgKwogICAgICAiXDAyMFwwMDBcMDIyIFxuXDAyNGZpZWxkX3NpbnQzMl9saXN0XzMzXDAzMCEgXDAwMyhcMDIxQlwwMDJcMDIwXDAwMFwwMjIgXG5cMDI0IiArCiAgICAgICJmaWVsZF9zaW50NjRfbGlzdF8zNFwwMzBcIiBcMDAzKFwwMjJCXDAwMlwwMjBcMDAwXDAyMlwnXG5cMDMzZmllbGRfIiArCiAgICAgICJkb3VibGVfbGlzdF9wYWNrZWRfMzVcMDMwIyBcMDAzKFwwMDFCXDAwMlwwMjBcMDAxXDAyMiZcblwwMzJmaWVsZCIgKwogICAgICAiX2Zsb2F0X2xpc3RfcGFja2VkXzM2XDAzMCQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMVwwMjImXG5cMDMyZmllbGQiICsKICAgICAgIl9pbnQ2NF9saXN0X3BhY2tlZF8zN1wwMzAlIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXCdcblwwMzNmaWVsZCIgKwogICAgICAiX3VpbnQ2NF9saXN0X3BhY2tlZF8zOFwwMzAmIFwwMDMoXDAwNEJcMDAyXDAyMFwwMDFcMDIyJlxuXDAzMmZpZWwiICsKICAgICAgImRfaW50MzJfbGlzdF9wYWNrZWRfMzlcMDMwXCcgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjIoXG5cMDM0ZmllbCIgKwogICAgICAiZF9maXhlZDY0X2xpc3RfcGFja2VkXzQwXDAzMCggXDAwMyhcMDA2QlwwMDJcMDIwXDAwMVwwMjIoXG5cMDM0ZmkiICsKICAgICAgImVsZF9maXhlZDMyX2xpc3RfcGFja2VkXzQxXDAzMCkgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMVwwMjIlXG5cMDMxIiArCiAgICAgICJmaWVsZF9ib29sX2xpc3RfcGFja2VkXzQyXDAzMCogXDAwMyhcMDEwQlwwMDJcMDIwXDAwMVwwMjJcJ1xuXDAzM2YiICsKICAgICAgImllbGRfdWludDMyX2xpc3RfcGFja2VkXzQzXDAzMCsgXDAwMyhcckJcMDAyXDAyMFwwMDFcMDIyWFxuXDAzMSIgKwogICAgICAiZmllbGRfZW51bV9saXN0X3BhY2tlZF80NFwwMzAsIFwwMDMoXDAxNjIxLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbiIgKwogICAgICAidW1CXDAwMlwwMjBcMDAxXDAyMilcblwwMzVmaWVsZF9zZml4ZWQzMl9saXN0X3BhY2tlZF80NVwwMzAiICsKICAgICAgIi0gXDAwMyhcMDE3QlwwMDJcMDIwXDAwMVwwMjIpXG5cMDM1ZmllbGRfc2ZpeGVkNjRfbGlzdF9wYWNrZWRfIiArCiAgICAgICI0NlwwMzAuIFwwMDMoXDAyMEJcMDAyXDAyMFwwMDFcMDIyXCdcblwwMzNmaWVsZF9zaW50MzJfbGlzdF9wYWNrZWQiICsKICAgICAgIl80N1wwMzAvIFwwMDMoXDAyMUJcMDAyXDAyMFwwMDFcMDIyXCdcblwwMzNmaWVsZF9zaW50NjRfbGlzdF9wYWNrZSIgKwogICAgICAiZF80OFwwMzAwIFwwMDMoXDAyMkJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXDAxN2ZpZWxkX2RvdWJsZV81M1wwMzA1IFwwMDEoXDAwMUgiICsKICAgICAgIlwwMDBcMDIyXDAzMFxuXDAxNmZpZWxkX2Zsb2F0XzU0XDAzMDYgXDAwMShcMDAySFwwMDBcMDIyXDAzMFxuXDAxNmZpZWxkX2ludCIgKwogICAgICAiNjRfNTVcMDMwNyBcMDAxKFwwMDNIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfdWludDY0XzU2XDAzMDggXDAwMShcMDA0SFwwMDAiICsKICAgICAgIlwwMjJcMDMwXG5cMDE2ZmllbGRfaW50MzJfNTdcMDMwOSBcMDAxKFwwMDVIXDAwMFwwMjJcMDMyXG5cMDIwZmllbGRfZml4ZSIgKwogICAgICAiZDY0XzU4XDAzMDogXDAwMShcMDA2SFwwMDBcMDIyXDAzMlxuXDAyMGZpZWxkX2ZpeGVkMzJfNTlcMDMwOyBcMDAxKFwwMDciICsKICAgICAgIkhcMDAwXDAyMlwwMjdcblxyZmllbGRfYm9vbF82MFwwMzA8IFwwMDEoXDAxMEhcMDAwXDAyMlwwMzFcblwwMTdmaWVsZF9zdHIiICsKICAgICAgImluZ182MVwwMzA9IFwwMDEoXHRIXDAwMFwwMjJEXG5cMDIwZmllbGRfbWVzc2FnZV82MlwwMzA+IFwwMDEoXDAxMyIgKwogICAgICAiMigucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaSIgKwogICAgICAidGVIXDAwMFwwMjJcMDMwXG5cMDE2ZmllbGRfYnl0ZXNfNjNcMDMwPyBcMDAxKFwwMTRIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfIiArCiAgICAgICJ1aW50MzJfNjRcMDMwQCBcMDAxKFxySFwwMDBcMDIyXDAzM1xuXDAyMWZpZWxkX3NmaXhlZDMyXzY1XDAzMEEiICsKICAgICAgIiBcMDAxKFwwMTdIXDAwMFwwMjJcMDMzXG5cMDIxZmllbGRfc2ZpeGVkNjRfNjZcMDMwQiBcMDAxKFwwMjBIXDAwMFwwMjJcMDMxXG5cMDE3ZiIgKwogICAgICAiaWVsZF9zaW50MzJfNjdcMDMwQyBcMDAxKFwwMjFIXDAwMFwwMjJcMDMxXG5cMDE3ZmllbGRfc2ludDY0XzYiICsKICAgICAgIjhcMDMwRCBcMDAxKFwwMjJIXDAwMFwiJlxuXDAxMFRlc3RFbnVtXDAyMlwwMTBcblwwMDRaRVJPXDAyMFwwMDBcMDIyXDAwN1xuXDAwM09ORVwwMjBcMDAxIiArCiAgICAgICJcMDIyXDAwN1xuXDAwM1RXT1wwMjBcMDAyQlwwMTRcblxudGVzdF9vbmVvZlwiXDAyMVxuXDAxN1Byb3RvM0VtcHR5TGkiICsKICAgICAgInRlXCJcMjYyXDI0NlwwMDJcblwwMzFQcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzXDAyMmZcblwwMjVmaWUiICsKICAgICAgImxkX21hcF9ib29sX2Jvb2xfMVwwMzBcMDAxIFwwMDMoXDAxMzJHLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGQiICsKICAgICAgIk1hcEJvb2xCb29sMUVudHJ5XDAyMmhcblwwMjZmaWVsZF9tYXBfYm9vbF9ieXRlIiArCiAgICAgICJzXzJcMDMwXDAwMiBcMDAzKFwwMTMySC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zIiArCiAgICAgICJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEJ5dGVzMkVuIiArCiAgICAgICJ0cnlcMDIyalxuXDAyN2ZpZWxkX21hcF9ib29sX2RvdWJsZV8zXDAzMFwwMDMgXDAwMyhcMDEzMkkucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaSIgKwogICAgICAidGhNYXBzLkZpZWxkTWFwQm9vbERvdWJsZTNFbnRyeVwwMjJmXG5cMDI1ZmllbGQiICsKICAgICAgIl9tYXBfYm9vbF9lbnVtXzRcMDMwXDAwNCBcMDAzKFwwMTMyRy5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBCb29sRW51bTRFbnRyeVwwMjJsXG5cMDMwZmllbGRfbWFwX2Jvb2xfZml4ZWQzIiArCiAgICAgICIyXzVcMDMwXDAwNSBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zIiArCiAgICAgICJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEZpeGVkMzI1IiArCiAgICAgICJFbnRyeVwwMjJsXG5cMDMwZmllbGRfbWFwX2Jvb2xfZml4ZWQ2NF82XDAzMFwwMDYgXDAwMyhcMDEzMiIgKwogICAgICAiSi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdCIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwQm9vbEZpeGVkNjQ2RW50cnlcMDIyaFxuXDAyNmYiICsKICAgICAgImllbGRfbWFwX2Jvb2xfZmxvYXRfN1wwMzBcMDA3IFwwMDMoXDAxMzJILnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmkiICsKICAgICAgImVsZE1hcEJvb2xGbG9hdDdFbnRyeVwwMjJoXG5cMDI2ZmllbGRfbWFwX2Jvb2xfIiArCiAgICAgICJpbnQzMl84XDAzMFwwMTAgXDAwMyhcMDEzMkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvb2xJbnQzIiArCiAgICAgICIyOEVudHJ5XDAyMmhcblwwMjZmaWVsZF9tYXBfYm9vbF9pbnQ2NF85XDAzMFx0IFwwMDMoXDAxMzIiICsKICAgICAgIkgucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXQiICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcEJvb2xJbnQ2NDlFbnRyeVwwMjJuXG5cMDMxZmllIiArCiAgICAgICJsZF9tYXBfYm9vbF9tZXNzYWdlXzEwXDAzMFxuIFwwMDMoXDAxMzJLLnByb3RvYnVmLiIgKwogICAgICAiZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeVwwMjJwXG5cMDMyZmllbGRfbWFwX2IiICsKICAgICAgIm9vbF9zZml4ZWQzMl8xMVwwMzBcMDEzIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW0iICsKICAgICAgImVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIkJvb2xTZml4ZWQzMjExRW50cnlcMDIycFxuXDAzMmZpZWxkX21hcF9ib29sX3NmIiArCiAgICAgICJpeGVkNjRfMTJcMDMwXDAxNCBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwQm9vbFNmIiArCiAgICAgICJpeGVkNjQxMkVudHJ5XDAyMmxcblwwMzBmaWVsZF9tYXBfYm9vbF9zaW50MzJfMSIgKwogICAgICAiM1wwMzBcciBcMDAzKFwwMTMySi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWUiICsKICAgICAgInNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwQm9vbFNpbnQzMjEzRW4iICsKICAgICAgInRyeVwwMjJsXG5cMDMwZmllbGRfbWFwX2Jvb2xfc2ludDY0XzE0XDAzMFwwMTYgXDAwMyhcMDEzMkouIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXIiArCiAgICAgICJpdGhNYXBzLkZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlcMDIybFxuXDAzMGZpZSIgKwogICAgICAibGRfbWFwX2Jvb2xfc3RyaW5nXzE1XDAzMFwwMTcgXDAwMyhcMDEzMkoucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwQm9vbFN0cmluZzE1RW50cnlcMDIybFxuXDAzMGZpZWxkX21hcF9ib28iICsKICAgICAgImxfdWludDMyXzE2XDAzMFwwMjAgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvb2wiICsKICAgICAgIlVpbnQzMjE2RW50cnlcMDIybFxuXDAzMGZpZWxkX21hcF9ib29sX3VpbnQ2NF8xIiArCiAgICAgICI3XDAzMFwwMjEgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lIiArCiAgICAgICJzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEJvb2xVaW50NjQxN0VuIiArCiAgICAgICJ0cnlcMDIyblxuXDAzMWZpZWxkX21hcF9maXhlZDMyX2Jvb2xfMThcMDMwXDAyMiBcMDAzKFwwMTMySyIgKwogICAgICAiLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZSIgKwogICAgICAiV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlcMDIycFxuXDAzMmYiICsKICAgICAgImllbGRfbWFwX2ZpeGVkMzJfYnl0ZXNfMTlcMDMwXDAyMyBcMDAzKFwwMTMyTC5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBGaXhlZDMyQnl0ZXMxOUVudHJ5XDAyMnJcblwwMzNmaWVsZF9tIiArCiAgICAgICJhcF9maXhlZDMyX2RvdWJsZV8yMFwwMzBcMDI0IFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4IiArCiAgICAgICJwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllIiArCiAgICAgICJsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5XDAyMm5cblwwMzFmaWVsZF9tYXBfZiIgKwogICAgICAiaXhlZDMyX2VudW1fMjFcMDMwXDAyNSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZSIgKwogICAgICAibnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRiIgKwogICAgICAiaXhlZDMyRW51bTIxRW50cnlcMDIydFxuXDAzNGZpZWxkX21hcF9maXhlZDMyX2YiICsKICAgICAgIml4ZWQzMl8yMlwwMzBcMDI2IFwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMiICsKICAgICAgIjJGaXhlZDMyMjJFbnRyeVwwMjJ0XG5cMDM0ZmllbGRfbWFwX2ZpeGVkMzJfZml4IiArCiAgICAgICJlZDY0XzIzXDAzMFwwMjcgXDAwMyhcMDEzMk4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJGIiArCiAgICAgICJpeGVkNjQyM0VudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXBfZml4ZWQzMl9mbG9hdCIgKwogICAgICAiXzI0XDAzMFwwMzAgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkMzJGbG9hdCIgKwogICAgICAiMjRFbnRyeVwwMjJwXG5cMDMyZmllbGRfbWFwX2ZpeGVkMzJfaW50MzJfMjVcMDMwXDAzMSAiICsKICAgICAgIlwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWciICsKICAgICAgImVMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMySW50MzIyNUVudHIiICsKICAgICAgInlcMDIycFxuXDAzMmZpZWxkX21hcF9maXhlZDMyX2ludDY0XzI2XDAzMFwwMzIgXDAwMyhcMDEzMkwuIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXIiArCiAgICAgICJpdGhNYXBzLkZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeVwwMjJ0XG5cMDM0ZiIgKwogICAgICAiaWVsZF9tYXBfZml4ZWQzMl9tZXNzYWdlXzI3XDAzMFwwMzMgXDAwMyhcMDEzMk4ucHJvdCIgKwogICAgICAib2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTSIgKwogICAgICAiYXBzLkZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5XDAyMnZcblwwMzVmaWUiICsKICAgICAgImxkX21hcF9maXhlZDMyX3NmaXhlZDMyXzI4XDAzMFwwMzQgXDAwMyhcMDEzMk8ucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeVwwMjJ2XG5cMDM1ZmllIiArCiAgICAgICJsZF9tYXBfZml4ZWQzMl9zZml4ZWQ2NF8yOVwwMzBcMDM1IFwwMDMoXDAxMzJPLnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlcMDIyclxuXDAzM2ZpZSIgKwogICAgICAibGRfbWFwX2ZpeGVkMzJfc2ludDMyXzMwXDAzMFwwMzYgXDAwMyhcMDEzMk0ucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlcMDIyclxuXDAzM2ZpZWxkX20iICsKICAgICAgImFwX2ZpeGVkMzJfc2ludDY0XzMxXDAzMFwwMzcgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWUiICsKICAgICAgImxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlcMDIyclxuXDAzM2ZpZWxkX21hcF9mIiArCiAgICAgICJpeGVkMzJfc3RyaW5nXzMyXDAzMCAgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwRml4ZWQzMlN0cmluZzMyRW50cnlcMDIyclxuXDAzM2ZpZWxkX21hcF9maXhlZCIgKwogICAgICAiMzJfdWludDMyXzMzXDAzMCEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeCIgKwogICAgICAiZWQzMlVpbnQzMjMzRW50cnlcMDIyclxuXDAzM2ZpZWxkX21hcF9maXhlZDMyX3UiICsKICAgICAgImludDY0XzM0XDAzMFwiIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QIiArCiAgICAgICJyb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDMyIiArCiAgICAgICJVaW50NjQzNEVudHJ5XDAyMm5cblwwMzFmaWVsZF9tYXBfZml4ZWQ2NF9ib29sXyIgKwogICAgICAiMzVcMDMwIyBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTSIgKwogICAgICAiZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEJvb2wzNSIgKwogICAgICAiRW50cnlcMDIycFxuXDAzMmZpZWxkX21hcF9maXhlZDY0X2J5dGVzXzM2XDAzMCQgXDAwMygiICsKICAgICAgIlwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUwiICsKICAgICAgIml0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeVwwMjIiICsKICAgICAgInJcblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9kb3VibGVfMzdcMDMwJSBcMDAzKFwwMTMyTS5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBGaXhlZDY0RG91YmxlMzdFbnRyeVwwMjJuXG5cMDMxZiIgKwogICAgICAiaWVsZF9tYXBfZml4ZWQ2NF9lbnVtXzM4XDAzMCYgXDAwMyhcMDEzMksucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5XDAyMnRcblwwMzRmaWVsZF9tYXAiICsKICAgICAgIl9maXhlZDY0X2ZpeGVkMzJfMzlcMDMwXCcgXDAwMyhcMDEzMk4ucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5XDAyMnRcblwwMzRmaWVsZF9tYXBfZiIgKwogICAgICAiaXhlZDY0X2ZpeGVkNjRfNDBcMDMwKCBcMDAzKFwwMTMyTi5wcm90b2J1Zi5leHBlciIgKwogICAgICAiaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlcMDIycFxuXDAzMmZpZWxkX21hcF9maXgiICsKICAgICAgImVkNjRfZmxvYXRfNDFcMDMwKSBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW4iICsKICAgICAgInRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRmkiICsKICAgICAgInhlZDY0RmxvYXQ0MUVudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXBfZml4ZWQ2NF9pIiArCiAgICAgICJudDMyXzQyXDAzMCogXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByIiArCiAgICAgICJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEZpeGVkNjRJIiArCiAgICAgICJudDMyNDJFbnRyeVwwMjJwXG5cMDMyZmllbGRfbWFwX2ZpeGVkNjRfaW50NjRfNCIgKwogICAgICAiM1wwMzArIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDY0SW50NjQ0MyIgKwogICAgICAiRW50cnlcMDIydFxuXDAzNGZpZWxkX21hcF9maXhlZDY0X21lc3NhZ2VfNDRcMDMwLCAiICsKICAgICAgIlwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWciICsKICAgICAgImVMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW4iICsKICAgICAgInRyeVwwMjJ2XG5cMDM1ZmllbGRfbWFwX2ZpeGVkNjRfc2ZpeGVkMzJfNDVcMDMwLSBcMDAzIiArCiAgICAgICIoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIiArCiAgICAgICJMaXRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDY0U2ZpeGVkMzI0NUVuIiArCiAgICAgICJ0cnlcMDIydlxuXDAzNWZpZWxkX21hcF9maXhlZDY0X3NmaXhlZDY0XzQ2XDAzMC4gXDAwMyIgKwogICAgICAiKFwwMTMyTy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSIgKwogICAgICAiTGl0ZVdpdGhNYXBzLkZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbiIgKwogICAgICAidHJ5XDAyMnJcblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9zaW50MzJfNDdcMDMwLyBcMDAzKFwwMTMiICsKICAgICAgIjJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGkiICsKICAgICAgInRlV2l0aE1hcHMuRmllbGRNYXBGaXhlZDY0U2ludDMyNDdFbnRyeVwwMjIiICsKICAgICAgInJcblwwMzNmaWVsZF9tYXBfZml4ZWQ2NF9zaW50NjRfNDhcMDMwMCBcMDAzKFwwMTMyTS5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBGaXhlZDY0U2ludDY0NDhFbnRyeVwwMjJyXG5cMDMzZiIgKwogICAgICAiaWVsZF9tYXBfZml4ZWQ2NF9zdHJpbmdfNDlcMDMwMSBcMDAzKFwwMTMyTS5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnRyeVwwMjJyXG5cMDMzZmllbGQiICsKICAgICAgIl9tYXBfZml4ZWQ2NF91aW50MzJfNTBcMDMwMiBcMDAzKFwwMTMyTS5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBGaXhlZDY0VWludDMyNTBFbnRyeVwwMjJyXG5cMDMzZmllbGRfbWFwIiArCiAgICAgICJfZml4ZWQ2NF91aW50NjRfNTFcMDMwMyBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBGaXhlZDY0VWludDY0NTFFbnRyeVwwMjJqXG5cMDI3ZmllbGRfbWFwX2ludCIgKwogICAgICAiMzJfYm9vbF81MlwwMzA0IFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMiIgKwogICAgICAiQm9vbDUyRW50cnlcMDIybFxuXDAzMGZpZWxkX21hcF9pbnQzMl9ieXRlc181M1wwMzAiICsKICAgICAgIjUgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDMyQnl0ZXM1M0VudHIiICsKICAgICAgInlcMDIyblxuXDAzMWZpZWxkX21hcF9pbnQzMl9kb3VibGVfNTRcMDMwNiBcMDAzKFwwMTMySy5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlcMDIyalxuXDAyN2ZpZSIgKwogICAgICAibGRfbWFwX2ludDMyX2VudW1fNTVcMDMwNyBcMDAzKFwwMTMySS5wcm90b2J1Zi5leCIgKwogICAgICAicGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZSIgKwogICAgICAibGRNYXBJbnQzMkVudW01NUVudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXBfaW50MzIiICsKICAgICAgIl9maXhlZDMyXzU2XDAzMDggXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGEiICsKICAgICAgImwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDMiICsKICAgICAgIjJGaXhlZDMyNTZFbnRyeVwwMjJwXG5cMDMyZmllbGRfbWFwX2ludDMyX2ZpeGVkIiArCiAgICAgICI2NF81N1wwMzA5IFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90IiArCiAgICAgICJvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMkZpeGVkIiArCiAgICAgICI2NDU3RW50cnlcMDIybFxuXDAzMGZpZWxkX21hcF9pbnQzMl9mbG9hdF81OFwwMzA6ICIgKwogICAgICAiXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZyIgKwogICAgICAiZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5XDAyMiIgKwogICAgICAibFxuXDAzMGZpZWxkX21hcF9pbnQzMl9pbnQzMl81OVwwMzA7IFwwMDMoXDAxMzJKLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE0iICsKICAgICAgImFwcy5GaWVsZE1hcEludDMySW50MzI1OUVudHJ5XDAyMmxcblwwMzBmaWVsZF9tIiArCiAgICAgICJhcF9pbnQzMl9pbnQ2NF82MFwwMzA8IFwwMDMoXDAxMzJKLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcEludDMySW50NjQ2MEVudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXBfaW50MzJfbSIgKwogICAgICAiZXNzYWdlXzYxXDAzMD0gXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDMyTSIgKwogICAgICAiZXNzYWdlNjFFbnRyeVwwMjJyXG5cMDMzZmllbGRfbWFwX2ludDMyX3NmaXhlZDMiICsKICAgICAgIjJfNjJcMDMwPiBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50MzJTZml4ZWQiICsKICAgICAgIjMyNjJFbnRyeVwwMjJyXG5cMDMzZmllbGRfbWFwX2ludDMyX3NmaXhlZDY0XzYzIiArCiAgICAgICJcMDMwPyBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzIiArCiAgICAgICJzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzIiArCiAgICAgICJFbnRyeVwwMjJuXG5cMDMxZmllbGRfbWFwX2ludDMyX3NpbnQzMl82NFwwMzBAIFwwMDMoXDAxMyIgKwogICAgICAiMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaSIgKwogICAgICAidGVXaXRoTWFwcy5GaWVsZE1hcEludDMyU2ludDMyNjRFbnRyeVwwMjJuXG4iICsKICAgICAgIlwwMzFmaWVsZF9tYXBfaW50MzJfc2ludDY0XzY1XDAzMEEgXDAwMyhcMDEzMksucHJvdG8iICsKICAgICAgImJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWEiICsKICAgICAgInBzLkZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5XDAyMm5cblwwMzFmaWVsZF9tIiArCiAgICAgICJhcF9pbnQzMl9zdHJpbmdfNjZcMDMwQiBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBJbnQzMlN0cmluZzY2RW50cnlcMDIyblxuXDAzMWZpZWxkX21hcF9pbnQzMiIgKwogICAgICAiX3VpbnQzMl82N1wwMzBDIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQzMiIgKwogICAgICAiVWludDMyNjdFbnRyeVwwMjJuXG5cMDMxZmllbGRfbWFwX2ludDMyX3VpbnQ2NF8iICsKICAgICAgIjY4XDAzMEQgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM00iICsKICAgICAgImVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDMyVWludDY0NjgiICsKICAgICAgIkVudHJ5XDAyMmpcblwwMjdmaWVsZF9tYXBfaW50NjRfYm9vbF82OVwwMzBFIFwwMDMoXDAxMzJJIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlcMDIybFxuXDAzMGZpZSIgKwogICAgICAibGRfbWFwX2ludDY0X2J5dGVzXzcwXDAzMEYgXDAwMyhcMDEzMkoucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwSW50NjRCeXRlczcwRW50cnlcMDIyblxuXDAzMWZpZWxkX21hcF9pbnQiICsKICAgICAgIjY0X2RvdWJsZV83MVwwMzBHIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQiICsKICAgICAgIjY0RG91YmxlNzFFbnRyeVwwMjJqXG5cMDI3ZmllbGRfbWFwX2ludDY0X2VudW1fIiArCiAgICAgICI3MlwwMzBIIFwwMDMoXDAxMzJJLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNIiArCiAgICAgICJlc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NEVudW03MkVuIiArCiAgICAgICJ0cnlcMDIycFxuXDAzMmZpZWxkX21hcF9pbnQ2NF9maXhlZDMyXzczXDAzMEkgXDAwMyhcMDEzMiIgKwogICAgICAiTC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdCIgKwogICAgICAiZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeVwwMjJwXG4iICsKICAgICAgIlwwMzJmaWVsZF9tYXBfaW50NjRfZml4ZWQ2NF83NFwwMzBKIFwwMDMoXDAxMzJMLnByb3QiICsKICAgICAgIm9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE0iICsKICAgICAgImFwcy5GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlcMDIybFxuXDAzMGZpZWxkIiArCiAgICAgICJfbWFwX2ludDY0X2Zsb2F0Xzc1XDAzMEsgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsIiArCiAgICAgICJkTWFwSW50NjRGbG9hdDc1RW50cnlcMDIybFxuXDAzMGZpZWxkX21hcF9pbnQ2NCIgKwogICAgICAiX2ludDMyXzc2XDAzMEwgXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDY0SSIgKwogICAgICAibnQzMjc2RW50cnlcMDIybFxuXDAzMGZpZWxkX21hcF9pbnQ2NF9pbnQ2NF83N1wwMzAiICsKICAgICAgIk0gXDAwMyhcMDEzMkoucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcEludDY0SW50NjQ3N0VudHIiICsKICAgICAgInlcMDIycFxuXDAzMmZpZWxkX21hcF9pbnQ2NF9tZXNzYWdlXzc4XDAzME4gXDAwMyhcMDEzMkwuIiArCiAgICAgICJwcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXIiArCiAgICAgICJpdGhNYXBzLkZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeVwwMjJyXG5cMDMzZiIgKwogICAgICAiaWVsZF9tYXBfaW50NjRfc2ZpeGVkMzJfNzlcMDMwTyBcMDAzKFwwMTMyTS5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBJbnQ2NFNmaXhlZDMyNzlFbnRyeVwwMjJyXG5cMDMzZmllbGQiICsKICAgICAgIl9tYXBfaW50NjRfc2ZpeGVkNjRfODBcMDMwUCBcMDAzKFwwMTMyTS5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBJbnQ2NFNmaXhlZDY0ODBFbnRyeVwwMjJuXG5cMDMxZmllbGRfbWFwIiArCiAgICAgICJfaW50NjRfc2ludDMyXzgxXDAzMFEgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwSW50NjRTaW50MzI4MUVudHJ5XDAyMm5cblwwMzFmaWVsZF9tYXBfaW50NjRfcyIgKwogICAgICAiaW50NjRfODJcMDMwUiBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwSW50NjRTaSIgKwogICAgICAibnQ2NDgyRW50cnlcMDIyblxuXDAzMWZpZWxkX21hcF9pbnQ2NF9zdHJpbmdfODMiICsKICAgICAgIlwwMzBTIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXMiICsKICAgICAgInNhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBJbnQ2NFN0cmluZzgzRW4iICsKICAgICAgInRyeVwwMjJuXG5cMDMxZmllbGRfbWFwX2ludDY0X3VpbnQzMl84NFwwMzBUIFwwMDMoXDAxMzJLIiArCiAgICAgICIucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlIiArCiAgICAgICJXaXRoTWFwcy5GaWVsZE1hcEludDY0VWludDMyODRFbnRyeVwwMjJuXG5cMDMxZiIgKwogICAgICAiaWVsZF9tYXBfaW50NjRfdWludDY0Xzg1XDAzMFUgXDAwMyhcMDEzMksucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwSW50NjRVaW50NjQ4NUVudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXAiICsKICAgICAgIl9zZml4ZWQzMl9ib29sXzg2XDAzMFYgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXIiICsKICAgICAgImltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE0iICsKICAgICAgImFwU2ZpeGVkMzJCb29sODZFbnRyeVwwMjJyXG5cMDMzZmllbGRfbWFwX3NmaXhlIiArCiAgICAgICJkMzJfYnl0ZXNfODdcMDMwVyBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50IiArCiAgICAgICJhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpIiArCiAgICAgICJ4ZWQzMkJ5dGVzODdFbnRyeVwwMjJ0XG5cMDM0ZmllbGRfbWFwX3NmaXhlZDMyXyIgKwogICAgICAiZG91YmxlXzg4XDAzMFggXDAwMyhcMDEzMk4ucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZCIgKwogICAgICAiMzJEb3VibGU4OEVudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXBfc2ZpeGVkMzJfZW4iICsKICAgICAgInVtXzg5XDAzMFkgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3QiICsKICAgICAgIm8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyRW4iICsKICAgICAgInVtODlFbnRyeVwwMjJ2XG5cMDM1ZmllbGRfbWFwX3NmaXhlZDMyX2ZpeGVkMzJfIiArCiAgICAgICI5MFwwMzBaIFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNIiArCiAgICAgICJlc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMkZpeGVkIiArCiAgICAgICIzMjkwRW50cnlcMDIydlxuXDAzNWZpZWxkX21hcF9zZml4ZWQzMl9maXhlZDY0XyIgKwogICAgICAiOTFcMDMwWyBcMDAzKFwwMTMyTy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTSIgKwogICAgICAiZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJGaXhlZCIgKwogICAgICAiNjQ5MUVudHJ5XDAyMnJcblwwMzNmaWVsZF9tYXBfc2ZpeGVkMzJfZmxvYXRfOTIiICsKICAgICAgIlwwMzBcXCBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzIiArCiAgICAgICJzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyIiArCiAgICAgICJFbnRyeVwwMjJyXG5cMDMzZmllbGRfbWFwX3NmaXhlZDMyX2ludDMyXzkzXDAzMF0gXDAwMyIgKwogICAgICAiKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZSIgKwogICAgICAiTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50ciIgKwogICAgICAieVwwMjJyXG5cMDMzZmllbGRfbWFwX3NmaXhlZDMyX2ludDY0Xzk0XDAzMF4gXDAwMyhcMDEzMk0iICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlcMDIydlxuIiArCiAgICAgICJcMDM1ZmllbGRfbWFwX3NmaXhlZDMyX21lc3NhZ2VfOTVcMDMwXyBcMDAzKFwwMTMyTy5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBTZml4ZWQzMk1lc3NhZ2U5NUVudHJ5XDAyMnhcbiIgKwogICAgICAiXDAzNmZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQzMl85NlwwMzBgIFwwMDMoXDAxMzJQLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlVyIgKwogICAgICAiaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5XDAyMiIgKwogICAgICAieFxuXDAzNmZpZWxkX21hcF9zZml4ZWQzMl9zZml4ZWQ2NF85N1wwMzBhIFwwMDMoXDAxMzIiICsKICAgICAgIlAucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXQiICsKICAgICAgImVXaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHIiICsKICAgICAgInlcMDIydFxuXDAzNGZpZWxkX21hcF9zZml4ZWQzMl9zaW50MzJfOThcMDMwYiBcMDAzKFwwMTMyIiArCiAgICAgICJOLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0IiArCiAgICAgICJlV2l0aE1hcHMuRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlcMDIyIiArCiAgICAgICJ0XG5cMDM0ZmllbGRfbWFwX3NmaXhlZDMyX3NpbnQ2NF85OVwwMzBjIFwwMDMoXDAxMzJOLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlVyIgKwogICAgICAiaXRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU2ludDY0OTlFbnRyeVwwMjJ2XG4iICsKICAgICAgIlwwMzVmaWVsZF9tYXBfc2ZpeGVkMzJfc3RyaW5nXzEwMFwwMzBkIFwwMDMoXDAxMzJPLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRW50cnlcMDIydlxuIiArCiAgICAgICJcMDM1ZmllbGRfbWFwX3NmaXhlZDMyX3VpbnQzMl8xMDFcMDMwZSBcMDAzKFwwMTMyTy5wIiArCiAgICAgICJyb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpIiArCiAgICAgICJ0aE1hcHMuRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5XDAyMnZcbiIgKwogICAgICAiXDAzNWZpZWxkX21hcF9zZml4ZWQzMl91aW50NjRfMTAyXDAzMGYgXDAwMyhcMDEzMk8ucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaSIgKwogICAgICAidGhNYXBzLkZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeVwwMjJyXG4iICsKICAgICAgIlwwMzNmaWVsZF9tYXBfc2ZpeGVkNjRfYm9vbF8xMDNcMDMwZyBcMDAzKFwwMTMyTS5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeVwwMjJ0XG5cMDM0ZmllIiArCiAgICAgICJsZF9tYXBfc2ZpeGVkNjRfYnl0ZXNfMTA0XDAzMGggXDAwMyhcMDEzMk4ucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5XDAyMnZcblwwMzVmaWVsZCIgKwogICAgICAiX21hcF9zZml4ZWQ2NF9kb3VibGVfMTA1XDAzMGkgXDAwMyhcMDEzMk8ucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeVwwMjJyXG5cMDMzZmllbGQiICsKICAgICAgIl9tYXBfc2ZpeGVkNjRfZW51bV8xMDZcMDMwaiBcMDAzKFwwMTMyTS5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeVwwMjJ4XG5cMDM2ZmllbGRfbWFwIiArCiAgICAgICJfc2ZpeGVkNjRfZml4ZWQzMl8xMDdcMDMwayBcMDAzKFwwMTMyUC5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeVwwMjJ4XG5cMDM2ZmllbGRfbSIgKwogICAgICAiYXBfc2ZpeGVkNjRfZml4ZWQ2NF8xMDhcMDMwbCBcMDAzKFwwMTMyUC5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLiIgKwogICAgICAiRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeVwwMjJ0XG5cMDM0ZmllbGQiICsKICAgICAgIl9tYXBfc2ZpeGVkNjRfZmxvYXRfMTA5XDAzMG0gXDAwMyhcMDEzMk4ucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwU2ZpeGVkNjRGbG9hdDEwOUVudHJ5XDAyMnRcblwwMzRmaWVsZF9tIiArCiAgICAgICJhcF9zZml4ZWQ2NF9pbnQzMl8xMTBcMDMwbiBcMDAzKFwwMTMyTi5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlcMDIydFxuXDAzNGZpZWxkX21hcCIgKwogICAgICAiX3NmaXhlZDY0X2ludDY0XzExMVwwMzBvIFwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbCIgKwogICAgICAiZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeVwwMjJ4XG5cMDM2ZmllbGRfbWFwX3MiICsKICAgICAgImZpeGVkNjRfbWVzc2FnZV8xMTJcMDMwcCBcMDAzKFwwMTMyUC5wcm90b2J1Zi5leHAiICsKICAgICAgImVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWwiICsKICAgICAgImRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeVwwMjJ6XG5cMDM3ZmllbGRfbWFwIiArCiAgICAgICJfc2ZpeGVkNjRfc2ZpeGVkMzJfMTEzXDAzMHEgXDAwMyhcMDEzMlEucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GIiArCiAgICAgICJpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5XDAyMnpcblwwMzdmaWVsZCIgKwogICAgICAiX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NF8xMTRcMDMwciBcMDAzKFwwMTMyUS5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0RW50cnlcMDIydlxuXDAzNWYiICsKICAgICAgImllbGRfbWFwX3NmaXhlZDY0X3NpbnQzMl8xMTVcMDMwcyBcMDAzKFwwMTMyTy5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUVudHJ5XDAyMnZcblwwMzVmIiArCiAgICAgICJpZWxkX21hcF9zZml4ZWQ2NF9zaW50NjRfMTE2XDAzMHQgXDAwMyhcMDEzMk8ucHJvIiArCiAgICAgICJ0b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoIiArCiAgICAgICJNYXBzLkZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeVwwMjJ2XG5cMDM1ZiIgKwogICAgICAiaWVsZF9tYXBfc2ZpeGVkNjRfc3RyaW5nXzExN1wwMzB1IFwwMDMoXDAxMzJPLnBybyIgKwogICAgICAidG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aCIgKwogICAgICAiTWFwcy5GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlcMDIydlxuXDAzNWYiICsKICAgICAgImllbGRfbWFwX3NmaXhlZDY0X3VpbnQzMl8xMThcMDMwdiBcMDAzKFwwMTMyTy5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOEVudHJ5XDAyMnZcblwwMzVmIiwKICAgICAgImllbGRfbWFwX3NmaXhlZDY0X3VpbnQ2NF8xMTlcMDMwdyBcMDAzKFwwMTMyTy5wcm8iICsKICAgICAgInRvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGgiICsKICAgICAgIk1hcHMuRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUVudHJ5XDAyMm5cblwwMzFmIiArCiAgICAgICJpZWxkX21hcF9zaW50MzJfYm9vbF8xMjBcMDMweCBcMDAzKFwwMTMySy5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzIiArCiAgICAgICIuRmllbGRNYXBTaW50MzJCb29sMTIwRW50cnlcMDIycFxuXDAzMmZpZWxkX21hcCIgKwogICAgICAiX3NpbnQzMl9ieXRlc18xMjFcMDMweSBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlciIgKwogICAgICAiaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTSIgKwogICAgICAiYXBTaW50MzJCeXRlczEyMUVudHJ5XDAyMnJcblwwMzNmaWVsZF9tYXBfc2ludDMiICsKICAgICAgIjJfZG91YmxlXzEyMlwwMzB6IFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW4iICsKICAgICAgInQzMkRvdWJsZTEyMkVudHJ5XDAyMm5cblwwMzFmaWVsZF9tYXBfc2ludDMyX2VuIiArCiAgICAgICJ1bV8xMjNcMDMweyBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvIiArCiAgICAgICJ0bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDMyRW51IiArCiAgICAgICJtMTIzRW50cnlcMDIydFxuXDAzNGZpZWxkX21hcF9zaW50MzJfZml4ZWQzMl8xMiIgKwogICAgICAiNFwwMzB8IFwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZSIgKwogICAgICAic3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50MzJGaXhlZDMyMSIgKwogICAgICAiMjRFbnRyeVwwMjJ0XG5cMDM0ZmllbGRfbWFwX3NpbnQzMl9maXhlZDY0XzEyNVwwMzAiICsKICAgICAgIn0gXDAwMyhcMDEzMk4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMkZpeGVkNjQxMjUiICsKICAgICAgIkVudHJ5XDAyMnBcblwwMzJmaWVsZF9tYXBfc2ludDMyX2Zsb2F0XzEyNlwwMzB+IFwwMDMoIiArCiAgICAgICJcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMIiArCiAgICAgICJpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlcMDIyIiArCiAgICAgICJwXG5cMDMyZmllbGRfbWFwX3NpbnQzMl9pbnQzMl8xMjdcMDMwXDE3NyBcMDAzKFwwMTMyTC5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdCIgKwogICAgICAiaE1hcHMuRmllbGRNYXBTaW50MzJJbnQzMjEyN0VudHJ5XDAyMnFcblwwMzJmaWUiICsKICAgICAgImxkX21hcF9zaW50MzJfaW50NjRfMTI4XDAzMFwyMDBcMDAxIFwwMDMoXDAxMzJMLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMiICsKICAgICAgIi5GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlcMDIydVxuXDAzNGZpZWxkX21hIiArCiAgICAgICJwX3NpbnQzMl9tZXNzYWdlXzEyOVwwMzBcMjAxXDAwMSBcMDAzKFwwMTMyTi5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTaW50MzJNZXNzYWdlMTI5RW50cnlcMDIyd1xuXDAzNWZpZWxkX21hcCIgKwogICAgICAiX3NpbnQzMl9zZml4ZWQzMl8xMzBcMDMwXDIwMlwwMDEgXDAwMyhcMDEzMk8ucHJvdG9idWYuZSIgKwogICAgICAieHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaSIgKwogICAgICAiZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeVwwMjJ3XG5cMDM1ZmllbGRfbWEiICsKICAgICAgInBfc2ludDMyX3NmaXhlZDY0XzEzMVwwMzBcMjAzXDAwMSBcMDAzKFwwMTMyTy5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUVudHJ5XDAyMnNcblwwMzNmaWVsZF9tIiArCiAgICAgICJhcF9zaW50MzJfc2ludDMyXzEzMlwwMzBcMjA0XDAwMSBcMDAzKFwwMTMyTS5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwXyIgKwogICAgICAic2ludDMyX3NpbnQ2NF8xMzNcMDMwXDIwNVwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZSIgKwogICAgICAicmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZCIgKwogICAgICAiTWFwU2ludDMyU2ludDY0MTMzRW50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF9zaW4iICsKICAgICAgInQzMl9zdHJpbmdfMTM0XDAzMFwyMDZcMDAxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW0iICsKICAgICAgImVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXAiICsKICAgICAgIlNpbnQzMlN0cmluZzEzNEVudHJ5XDAyMnNcblwwMzNmaWVsZF9tYXBfc2ludDMyIiArCiAgICAgICJfdWludDMyXzEzNVwwMzBcMjA3XDAwMSBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50IiArCiAgICAgICJhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2luIiArCiAgICAgICJ0MzJVaW50MzIxMzVFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3NpbnQzMl91aSIgKwogICAgICAibnQ2NF8xMzZcMDMwXDIxMFwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQzMiIgKwogICAgICAiVWludDY0MTM2RW50cnlcMDIyb1xuXDAzMWZpZWxkX21hcF9zaW50NjRfYm9vbF8iICsKICAgICAgIjEzN1wwMzBcMjExXDAwMSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0Qm9vbDEiICsKICAgICAgIjM3RW50cnlcMDIycVxuXDAzMmZpZWxkX21hcF9zaW50NjRfYnl0ZXNfMTM4XDAzMFwyMTJcMDAxIiArCiAgICAgICIgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhIiArCiAgICAgICJnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50IiArCiAgICAgICJyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF9kb3VibGVfMTM5XDAzMFwyMTNcMDAxIFwwMDMoXDAxMyIgKwogICAgICAiMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaSIgKwogICAgICAidGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5XDAyMiIgKwogICAgICAib1xuXDAzMWZpZWxkX21hcF9zaW50NjRfZW51bV8xNDBcMDMwXDIxNFwwMDEgXDAwMyhcMDEzMksucHIiICsKICAgICAgIm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXQiICsKICAgICAgImhNYXBzLkZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5XDAyMnVcblwwMzRmaWVsIiArCiAgICAgICJkX21hcF9zaW50NjRfZml4ZWQzMl8xNDFcMDMwXDIxNVwwMDEgXDAwMyhcMDEzMk4ucHJvdG9iIiArCiAgICAgICJ1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwIiArCiAgICAgICJzLkZpZWxkTWFwU2ludDY0Rml4ZWQzMjE0MUVudHJ5XDAyMnVcblwwMzRmaWVsZCIgKwogICAgICAiX21hcF9zaW50NjRfZml4ZWQ2NF8xNDJcMDMwXDIxNlwwMDEgXDAwMyhcMDEzMk4ucHJvdG9idSIgKwogICAgICAiZi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcyIgKwogICAgICAiLkZpZWxkTWFwU2ludDY0Rml4ZWQ2NDE0MkVudHJ5XDAyMnFcblwwMzJmaWVsZF8iICsKICAgICAgIm1hcF9zaW50NjRfZmxvYXRfMTQzXDAzMFwyMTdcMDAxIFwwMDMoXDAxMzJMLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmkiICsKICAgICAgImVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlcMDIycVxuXDAzMmZpZWxkX21hcF9zIiArCiAgICAgICJpbnQ2NF9pbnQzMl8xNDRcMDMwXDIyMFwwMDEgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpIiArCiAgICAgICJtZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hIiArCiAgICAgICJwU2ludDY0SW50MzIxNDRFbnRyeVwwMjJxXG5cMDMyZmllbGRfbWFwX3NpbnQ2NCIgKwogICAgICAiX2ludDY0XzE0NVwwMzBcMjIxXDAwMSBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW50YSIgKwogICAgICAibC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludCIgKwogICAgICAiNjRJbnQ2NDE0NUVudHJ5XDAyMnVcblwwMzRmaWVsZF9tYXBfc2ludDY0X21lc3MiICsKICAgICAgImFnZV8xNDZcMDMwXDIyMlwwMDEgXDAwMyhcMDEzMk4ucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NE0iICsKICAgICAgImVzc2FnZTE0NkVudHJ5XDAyMndcblwwMzVmaWVsZF9tYXBfc2ludDY0X3NmaXhlIiArCiAgICAgICJkMzJfMTQ3XDAzMFwyMjNcMDAxIFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5QIiArCiAgICAgICJyb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRTIiArCiAgICAgICJmaXhlZDMyMTQ3RW50cnlcMDIyd1xuXDAzNWZpZWxkX21hcF9zaW50NjRfc2ZpeCIgKwogICAgICAiZWQ2NF8xNDhcMDMwXDIyNFwwMDEgXDAwMyhcMDEzMk8ucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NCIgKwogICAgICAiU2ZpeGVkNjQxNDhFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF9zaW4iICsKICAgICAgInQzMl8xNDlcMDMwXDIyNVwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NFMiICsKICAgICAgImludDMyMTQ5RW50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF9zaW50NjRfc2ludDY0IiArCiAgICAgICJfMTUwXDAzMFwyMjZcMDAxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90IiArCiAgICAgICJvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRTaW50IiArCiAgICAgICI2NDE1MEVudHJ5XDAyMnNcblwwMzNmaWVsZF9tYXBfc2ludDY0X3N0cmluZ18xNSIgKwogICAgICAiMVwwMzBcMjI3XDAwMSBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTSIgKwogICAgICAiZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU2ludDY0U3RyaW5nMSIgKwogICAgICAiNTFFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3NpbnQ2NF91aW50MzJfMTUyXDAzMFwyMzAiICsKICAgICAgIlwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkUiICsKICAgICAgIm50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF9zaW50NjRfdWludDY0XzE1M1wwMzBcMjMxXDAwMSBcMDAzIiArCiAgICAgICIoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIiArCiAgICAgICJMaXRlV2l0aE1hcHMuRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyIiArCiAgICAgICJ5XDAyMm9cblwwMzFmaWVsZF9tYXBfc3RyaW5nX2Jvb2xfMTU0XDAzMFwyMzJcMDAxIFwwMDMoXDAxMzJLLiIgKwogICAgICAicHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlVyIgKwogICAgICAiaXRoTWFwcy5GaWVsZE1hcFN0cmluZ0Jvb2wxNTRFbnRyeVwwMjJxXG5cMDMyZmkiICsKICAgICAgImVsZF9tYXBfc3RyaW5nX2J5dGVzXzE1NVwwMzBcMjMzXDAwMSBcMDAzKFwwMTMyTC5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5XDAyMnNcblwwMzNmaWVsZF9tIiArCiAgICAgICJhcF9zdHJpbmdfZG91YmxlXzE1NlwwMzBcMjM0XDAwMSBcMDAzKFwwMTMyTS5wcm90b2J1Zi5lIiArCiAgICAgICJ4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpIiArCiAgICAgICJlbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeVwwMjJvXG5cMDMxZmllbGRfbWFwXyIgKwogICAgICAic3RyaW5nX2VudW1fMTU3XDAzMFwyMzVcMDAxIFwwMDMoXDAxMzJLLnByb3RvYnVmLmV4cGVyaSIgKwogICAgICAibWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYSIgKwogICAgICAicFN0cmluZ0VudW0xNTdFbnRyeVwwMjJ1XG5cMDM0ZmllbGRfbWFwX3N0cmluZ18iICsKICAgICAgImZpeGVkMzJfMTU4XDAzMFwyMzZcMDAxIFwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnQiICsKICAgICAgImFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTdHIiICsKICAgICAgImluZ0ZpeGVkMzIxNThFbnRyeVwwMjJ1XG5cMDM0ZmllbGRfbWFwX3N0cmluZ19mIiArCiAgICAgICJpeGVkNjRfMTU5XDAzMFwyMzdcMDAxIFwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnRhIiArCiAgICAgICJsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTdHJpIiArCiAgICAgICJuZ0ZpeGVkNjQxNTlFbnRyeVwwMjJxXG5cMDMyZmllbGRfbWFwX3N0cmluZ19mbCIgKwogICAgICAib2F0XzE2MFwwMzBcMjQwXDAwMSBcMDAzKFwwMTMyTC5wcm90b2J1Zi5leHBlcmltZW50YWwuUCIgKwogICAgICAicm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nRiIgKwogICAgICAibG9hdDE2MEVudHJ5XDAyMnFcblwwMzJmaWVsZF9tYXBfc3RyaW5nX2ludDMyXzEiICsKICAgICAgIjYxXDAzMFwyNDFcMDAxIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzMiICsKICAgICAgIk1lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdJbnQzMjEiICsKICAgICAgIjYxRW50cnlcMDIycVxuXDAzMmZpZWxkX21hcF9zdHJpbmdfaW50NjRfMTYyXDAzMFwyNDJcMDAxIiArCiAgICAgICIgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhIiArCiAgICAgICJnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50IiArCiAgICAgICJyeVwwMjJ1XG5cMDM0ZmllbGRfbWFwX3N0cmluZ19tZXNzYWdlXzE2M1wwMzBcMjQzXDAwMSBcMDAzKCIgKwogICAgICAiXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50ciIgKwogICAgICAieVwwMjJ3XG5cMDM1ZmllbGRfbWFwX3N0cmluZ19zZml4ZWQzMl8xNjRcMDMwXDI0NFwwMDEgXDAwMygiICsKICAgICAgIlwwMTMyTy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUwiICsKICAgICAgIml0ZVdpdGhNYXBzLkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnQiICsKICAgICAgInJ5XDAyMndcblwwMzVmaWVsZF9tYXBfc3RyaW5nX3NmaXhlZDY0XzE2NVwwMzBcMjQ1XDAwMSBcMDAzIiArCiAgICAgICIoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlIiArCiAgICAgICJMaXRlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUVuIiArCiAgICAgICJ0cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF9zdHJpbmdfc2ludDMyXzE2NlwwMzBcMjQ2XDAwMSBcMDAzKCIgKwogICAgICAiXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aE1hcHMuRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeSIgKwogICAgICAiXDAyMnNcblwwMzNmaWVsZF9tYXBfc3RyaW5nX3NpbnQ2NF8xNjdcMDMwXDI0N1wwMDEgXDAwMyhcMDEzMk0iICsKICAgICAgIi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUiICsKICAgICAgIldpdGhNYXBzLkZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlcMDIyc1xuIiArCiAgICAgICJcMDMzZmllbGRfbWFwX3N0cmluZ19zdHJpbmdfMTY4XDAzMFwyNTBcMDAxIFwwMDMoXDAxMzJNLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0IiArCiAgICAgICJoTWFwcy5GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5XDAyMnNcblwwMzNmaSIgKwogICAgICAiZWxkX21hcF9zdHJpbmdfdWludDMyXzE2OVwwMzBcMjUxXDAwMSBcMDAzKFwwMTMyTS5wcm90byIgKwogICAgICAiYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYSIgKwogICAgICAicHMuRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeVwwMjJzXG5cMDMzZmllbGQiICsKICAgICAgIl9tYXBfc3RyaW5nX3VpbnQ2NF8xNzBcMDMwXDI1MlwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlcMDIyb1xuXDAzMWZpZWxkX21hIiArCiAgICAgICJwX3VpbnQzMl9ib29sXzE3MVwwMzBcMjUzXDAwMSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkIiArCiAgICAgICJNYXBVaW50MzJCb29sMTcxRW50cnlcMDIycVxuXDAzMmZpZWxkX21hcF91aW50MyIgKwogICAgICAiMl9ieXRlc18xNzJcMDMwXDI1NFwwMDEgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbiIgKwogICAgICAidDMyQnl0ZXMxNzJFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3VpbnQzMl9kb3UiICsKICAgICAgImJsZV8xNzNcMDMwXDI1NVwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlAiICsKICAgICAgInJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkQiICsKICAgICAgIm91YmxlMTczRW50cnlcMDIyb1xuXDAzMWZpZWxkX21hcF91aW50MzJfZW51bV8xIiArCiAgICAgICI3NFwwMzBcMjU2XDAwMSBcMDAzKFwwMTMySy5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zIiArCiAgICAgICJNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyRW51bTE3IiArCiAgICAgICI0RW50cnlcMDIydVxuXDAzNGZpZWxkX21hcF91aW50MzJfZml4ZWQzMl8xNzVcMDMwXDI1NyIgKwogICAgICAiXDAwMSBcMDAzKFwwMTMyTi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzcyIgKwogICAgICAiYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyRml4ZWQzMjE3NSIgKwogICAgICAiRW50cnlcMDIydVxuXDAzNGZpZWxkX21hcF91aW50MzJfZml4ZWQ2NF8xNzZcMDMwXDI2MFwwMDEiICsKICAgICAgIiBcMDAzKFwwMTMyTi5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2EiICsKICAgICAgImdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkUiICsKICAgICAgIm50cnlcMDIycVxuXDAzMmZpZWxkX21hcF91aW50MzJfZmxvYXRfMTc3XDAzMFwyNjFcMDAxIFwwMDMoIiArCiAgICAgICJcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMIiArCiAgICAgICJpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlcMDIyIiArCiAgICAgICJxXG5cMDMyZmllbGRfbWFwX3VpbnQzMl9pbnQzMl8xNzhcMDMwXDI2MlwwMDEgXDAwMyhcMDEzMkwucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaSIgKwogICAgICAidGhNYXBzLkZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeVwwMjJxXG5cMDMyZmkiICsKICAgICAgImVsZF9tYXBfdWludDMyX2ludDY0XzE3OVwwMzBcMjYzXDAwMSBcMDAzKFwwMTMyTC5wcm90b2IiICsKICAgICAgInVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXAiICsKICAgICAgInMuRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5XDAyMnVcblwwMzRmaWVsZF9tIiArCiAgICAgICJhcF91aW50MzJfbWVzc2FnZV8xODBcMDMwXDI2NFwwMDEgXDAwMyhcMDEzMk4ucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GIiArCiAgICAgICJpZWxkTWFwVWludDMyTWVzc2FnZTE4MEVudHJ5XDAyMndcblwwMzVmaWVsZF9tYSIgKwogICAgICAicF91aW50MzJfc2ZpeGVkMzJfMTgxXDAzMFwyNjVcMDAxIFwwMDMoXDAxMzJPLnByb3RvYnVmLiIgKwogICAgICAiZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRiIgKwogICAgICAiaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlcMDIyd1xuXDAzNWZpZWxkX20iICsKICAgICAgImFwX3VpbnQzMl9zZml4ZWQ2NF8xODJcMDMwXDI2NlwwMDEgXDAwMyhcMDEzMk8ucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy4iICsKICAgICAgIkZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeVwwMjJzXG5cMDMzZmllbGRfIiArCiAgICAgICJtYXBfdWludDMyX3NpbnQzMl8xODNcMDMwXDI2N1wwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuIiArCiAgICAgICJleHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GIiArCiAgICAgICJpZWxkTWFwVWludDMyU2ludDMyMTgzRW50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcCIgKwogICAgICAiX3VpbnQzMl9zaW50NjRfMTg0XDAzMFwyNzBcMDAxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cCIgKwogICAgICAiZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbCIgKwogICAgICAiZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5XDAyMnNcblwwMzNmaWVsZF9tYXBfdWkiICsKICAgICAgIm50MzJfc3RyaW5nXzE4NVwwMzBcMjcxXDAwMSBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmkiICsKICAgICAgIm1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWEiICsKICAgICAgInBVaW50MzJTdHJpbmcxODVFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3VpbnQzIiArCiAgICAgICIyX3VpbnQzMl8xODZcMDMwXDI3MlwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVuIiArCiAgICAgICJ0YWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpIiArCiAgICAgICJudDMyVWludDMyMTg2RW50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF91aW50MzJfdSIgKwogICAgICAiaW50NjRfMTg3XDAzMFwyNzNcMDAxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50MyIgKwogICAgICAiMlVpbnQ2NDE4N0VudHJ5XDAyMm9cblwwMzFmaWVsZF9tYXBfdWludDY0X2Jvb2wiICsKICAgICAgIl8xODhcMDMwXDI3NFwwMDEgXDAwMyhcMDEzMksucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3QiICsKICAgICAgIm8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NEJvb2wiICsKICAgICAgIjE4OEVudHJ5XDAyMnFcblwwMzJmaWVsZF9tYXBfdWludDY0X2J5dGVzXzE4OVwwMzBcMjc1IiArCiAgICAgICJcMDAxIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzIiArCiAgICAgICJhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50NjRCeXRlczE4OUVuIiArCiAgICAgICJ0cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF91aW50NjRfZG91YmxlXzE5MFwwMzBcMjc2XDAwMSBcMDAzKCIgKwogICAgICAiXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTCIgKwogICAgICAiaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeSIgKwogICAgICAiXDAyMm9cblwwMzFmaWVsZF9tYXBfdWludDY0X2VudW1fMTkxXDAzMFwyNzdcMDAxIFwwMDMoXDAxMzJLLnAiICsKICAgICAgInJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2kiICsKICAgICAgInRoTWFwcy5GaWVsZE1hcFVpbnQ2NEVudW0xOTFFbnRyeVwwMjJ1XG5cMDM0ZmllIiArCiAgICAgICJsZF9tYXBfdWludDY0X2ZpeGVkMzJfMTkyXDAzMFwzMDBcMDAxIFwwMDMoXDAxMzJOLnByb3RvIiArCiAgICAgICJidWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hIiArCiAgICAgICJwcy5GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeVwwMjJ1XG5cMDM0ZmllbCIgKwogICAgICAiZF9tYXBfdWludDY0X2ZpeGVkNjRfMTkzXDAzMFwzMDFcMDAxIFwwMDMoXDAxMzJOLnByb3RvYiIgKwogICAgICAidWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcCIgKwogICAgICAicy5GaWVsZE1hcFVpbnQ2NEZpeGVkNjQxOTNFbnRyeVwwMjJxXG5cMDMyZmllbGQiICsKICAgICAgIl9tYXBfdWludDY0X2Zsb2F0XzE5NFwwMzBcMzAyXDAwMSBcMDAzKFwwMTMyTC5wcm90b2J1Zi4iICsKICAgICAgImV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkYiICsKICAgICAgImllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5XDAyMnFcblwwMzJmaWVsZF9tYXBfIiArCiAgICAgICJ1aW50NjRfaW50MzJfMTk1XDAzMFwzMDNcMDAxIFwwMDMoXDAxMzJMLnByb3RvYnVmLmV4cGVyIiArCiAgICAgICJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNIiArCiAgICAgICJhcFVpbnQ2NEludDMyMTk1RW50cnlcMDIycVxuXDAzMmZpZWxkX21hcF91aW50NiIgKwogICAgICAiNF9pbnQ2NF8xOTZcMDMwXDMwNFwwMDEgXDAwMyhcMDEzMkwucHJvdG9idWYuZXhwZXJpbWVudCIgKwogICAgICAiYWwuUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbiIgKwogICAgICAidDY0SW50NjQxOTZFbnRyeVwwMjJ1XG5cMDM0ZmllbGRfbWFwX3VpbnQ2NF9tZXMiICsKICAgICAgInNhZ2VfMTk3XDAzMFwzMDVcMDAxIFwwMDMoXDAxMzJOLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50NjQiICsKICAgICAgIk1lc3NhZ2UxOTdFbnRyeVwwMjJ3XG5cMDM1ZmllbGRfbWFwX3VpbnQ2NF9zZml4IiArCiAgICAgICJlZDMyXzE5OFwwMzBcMzA2XDAwMSBcMDAzKFwwMTMyTy5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0IiArCiAgICAgICJTZml4ZWQzMjE5OEVudHJ5XDAyMndcblwwMzVmaWVsZF9tYXBfdWludDY0X3NmaSIgKwogICAgICAieGVkNjRfMTk5XDAzMFwzMDdcMDAxIFwwMDMoXDAxMzJPLnByb3RvYnVmLmV4cGVyaW1lbnRhbCIgKwogICAgICAiLlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50NiIgKwogICAgICAiNFNmaXhlZDY0MTk5RW50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF91aW50NjRfc2kiICsKICAgICAgIm50MzJfMjAwXDAzMFwzMTBcMDAxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC4iICsKICAgICAgIlByb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50NjQiICsKICAgICAgIlNpbnQzMjIwMEVudHJ5XDAyMnNcblwwMzNmaWVsZF9tYXBfdWludDY0X3NpbnQ2IiArCiAgICAgICI0XzIwMVwwMzBcMzExXDAwMSBcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvIiArCiAgICAgICJ0bzNNZXNzYWdlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0U2luIiArCiAgICAgICJ0NjQyMDFFbnRyeVwwMjJzXG5cMDMzZmllbGRfbWFwX3VpbnQ2NF9zdHJpbmdfMiIgKwogICAgICAiMDJcMDMwXDMxMlwwMDEgXDAwMyhcMDEzMk0ucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvMyIgKwogICAgICAiTWVzc2FnZUxpdGVXaXRoTWFwcy5GaWVsZE1hcFVpbnQ2NFN0cmluZyIgKwogICAgICAiMjAyRW50cnlcMDIyc1xuXDAzM2ZpZWxkX21hcF91aW50NjRfdWludDMyXzIwM1wwMzAiICsKICAgICAgIlwzMTNcMDAxIFwwMDMoXDAxMzJNLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXMiICsKICAgICAgInNhZ2VMaXRlV2l0aE1hcHMuRmllbGRNYXBVaW50NjRVaW50MzIyMDMiICsKICAgICAgIkVudHJ5XDAyMnNcblwwMzNmaWVsZF9tYXBfdWludDY0X3VpbnQ2NF8yMDRcMDMwXDMxNFwwMDEgIiArCiAgICAgICJcMDAzKFwwMTMyTS5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnIiArCiAgICAgICJlTGl0ZVdpdGhNYXBzLkZpZWxkTWFwVWludDY0VWludDY0MjA0RW50IiArCiAgICAgICJyeVwwMzI4XG5cMDI2RmllbGRNYXBCb29sQm9vbDFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWxkTWFwQm9vbEJ5dGUiICsKICAgICAgInMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzIiICsKICAgICAgIjpcblwwMzBGaWVsZE1hcEJvb2xEb3VibGUzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMCIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMmtcblwwMjZGaWVsZE1hcEJvb2xFbnVtNCIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJAXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyMS5wcm90IiArCiAgICAgICJvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0IiArCiAgICAgICJFbnVtOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWEiICsKICAgICAgInBCb29sRml4ZWQ2NDZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWxkTWFwQm9vbEZsb2F0N0VudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI5XG5cMDI3RmllbGRNYSIgKwogICAgICAicEJvb2xJbnQzMjhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyOVxuXDAyN0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJmXG5cMDMyRmllbGRNYXBCIiArCiAgICAgICJvb2xNZXNzYWdlMTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMjdcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDEzMigucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3MiICsKICAgICAgImFnZUxpdGU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMj1cblwwMzNGaSIgKwogICAgICAiZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyIiArCiAgICAgICJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwQm9vbFNpbnQzMjEiICsKICAgICAgIjNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMjsiICsKICAgICAgIlxuXDAzMUZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMCIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xTdHJpbiIgKwogICAgICAiZzE1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI7XG5cMDMxRmllbGRNYXBCb29sVWludDMyMTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEJvb2xVaW4iICsKICAgICAgInQ2NDE3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEZpeGVkMzJCb29sMThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZSIgKwogICAgICAiZDMyQnl0ZXMxOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDMyRG91YmxlMjBFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyb1xuXDAzMkZpZWxkIiArCiAgICAgICJNYXBGaXhlZDMyRW51bTIxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJAXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIxLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzMiICsKICAgICAgIk1lc3NhZ2VMaXRlLlRlc3RFbnVtOlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBGaXhlIiArCiAgICAgICJkMzJGaXhlZDMyMjJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmkiICsKICAgICAgImVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcciIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkMzJJbnQzIiArCiAgICAgICIyMjVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyaVxuXDAzNUZpZWxkTWFwRml4ZWQiICsKICAgICAgIjMyTWVzc2FnZTI3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjI3XG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAxMzIoLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYSIgKwogICAgICAiZ2VMaXRlOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBGaXhlZDMyU2ZpeGVkMzIyOEUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2IiArCiAgICAgICJGaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxICIgKwogICAgICAiXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMyIgKwogICAgICAiMlNpbnQzMjMwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNIiArCiAgICAgICJhcEZpeGVkMzJTdHJpbmczMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRml4ZWQzMlVpbnQzMjMiICsKICAgICAgIjNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+IiArCiAgICAgICJcblwwMzRGaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBGaXhlZDYiICsKICAgICAgIjRCb29sMzVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTAiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwRiIgKwogICAgICAiaXhlZDY0RG91YmxlMzdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyb1xuXDAzMkZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJAXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyMS5wcm90b2J1ZiIgKwogICAgICAiLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hIiArCiAgICAgICJwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG4iICsKICAgICAgIlwwMzNGaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEZpeGVkNjRJIiArCiAgICAgICJudDY0NDNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyaVxuXDAzNUZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjI3XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyKC5wcm90b2J1Zi5leHBlIiArCiAgICAgICJyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTSIgKwogICAgICAiYXBGaXhlZDY0U2ZpeGVkMzI0NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBGaXhlZDY0U2ZpeGUiICsKICAgICAgImQ2NDQ2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXDAwNlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaSIgKwogICAgICAieGVkNjRTaW50NjQ0OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDY0U3RyaW5nNDlFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaSIgKwogICAgICAiZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBGaXhlZDY0VWluIiArCiAgICAgICJ0NjQ1MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDZcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI6XG5cMDMwRmllbGRNYXBJbnQzMkJvb2w1MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJbnQzMkIiICsKICAgICAgInl0ZXM1M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDoiICsKICAgICAgIlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMm1cblwwMzBGaWVsZE1hcEludCIgKwogICAgICAiMzJFbnVtNTVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMkBcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoIiArCiAgICAgICJcMDE2MjEucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMIiArCiAgICAgICJpdGUuVGVzdEVudW06XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludDMyRml4ZWQzMiIgKwogICAgICAiNTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMiIgKwogICAgICAiPVxuXDAzM0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50MzJGIiArCiAgICAgICJsb2F0NThFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDMiICsKICAgICAgIjJJbnQ2NDYwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSgiICsKICAgICAgIlwwMDM6XDAwMjhcMDAxXDAzMmdcblwwMzNGaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjdcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIoLnByb3RvYnVmLmV4cGUiICsKICAgICAgInJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNIiArCiAgICAgICJhcEludDMyU2ZpeGVkMzI2MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBJbnQzMlNmaXhlZDY0NiIgKwogICAgICAiM0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyPCIgKwogICAgICAiXG5cMDMyRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDMyU2luIiArCiAgICAgICJ0NjQ2NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQzIiArCiAgICAgICIyVWludDMyNjdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXHI6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDMyVWludDY0NjhFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyOlxuXDAzMEZpZWxkTWFwIiArCiAgICAgICJJbnQ2NEJvb2w2OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI7XG5cMDMxRmllbGRNYXBJbnQ2NEJ5dGVzNzBFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWEiICsKICAgICAgInBJbnQ2NERvdWJsZTcxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMm1cblwwMzBGaWVsZE1hcEludDY0RW51bTcyRW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMkBcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIxLnByb3RvYnVmLmUiICsKICAgICAgInhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlc3RFbnVtOlwwMDIiICsKICAgICAgIjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcEludCIgKwogICAgICAiNjRGaXhlZDY0NzRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyO1xuXDAzMUZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hIiArCiAgICAgICJwSW50NjRJbnQzMjc2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjtcblwwMzFGaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJnXG5cMDMzRmllbGQiICsKICAgICAgIk1hcEludDY0TWVzc2FnZTc4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjI3XG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIoLnByb3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90byIgKwogICAgICAiM01lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBJbnQ2NFNmaXhlZDMiICsKICAgICAgIjI3OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI+XG5cMDM0RmllbGRNYXBJbnQ2NFNmaXhlZDY0ODBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwSW50NiIgKwogICAgICAiNFNpbnQzMjgxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMjE6XDAwMjhcMDAxXDAzMjxcblwwMzJGaWVsZE1hcEludDY0U2ludDY0ODJFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwIiArCiAgICAgICJJbnQ2NFN0cmluZzgzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbCIgKwogICAgICAiZE1hcEludDY0VWludDY0ODVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMlxyXG5cMDA1diIgKwogICAgICAiYWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ZpeGVkMzJCb29sODYiICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPlxuIiArCiAgICAgICJcMDM0RmllbGRNYXBTZml4ZWQzMkJ5dGVzODdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwU2ZpeGVkMyIgKwogICAgICAiMkRvdWJsZTg4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIsCiAgICAgICIoXDAwMTpcMDAyOFwwMDFcMDMycFxuXDAzM0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyQFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjEucHJvdG9idWYuZXhwIiArCiAgICAgICJlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjhcMDAxIiArCiAgICAgICJcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2YiICsKICAgICAgIml4ZWQzMkZpeGVkNjQ5MUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTZml4ZWQzMkZsb2F0OTJFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPlxuXDAzNCIgKwogICAgICAiRmllbGRNYXBTZml4ZWQzMkludDMyOTNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ZpeGVkMzIiICsKICAgICAgIkludDY0OTRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDMiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyalxuXDAzNkZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyN1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMigucHJvdG9idWYuZXgiICsKICAgICAgInBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGU6XDAwMjhcMDAxXDAzMkFcblwwMzdGaWVsIiArCiAgICAgICJkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxNyIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTc6XDAwMjhcMDAxXDAzMkFcblwwMzdGaWVsZE1hcFNmaXhlZDMyUyIgKwogICAgICAiZml4ZWQ2NDk3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMjA6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDMyU2ludDMyOThFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkIiArCiAgICAgICJNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjI6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDMyU3RyaSIgKwogICAgICAibmcxMDBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDE3XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXAiICsKICAgICAgIlNmaXhlZDMyVWludDY0MTAyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMDQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwIiArCiAgICAgICIzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI/IiArCiAgICAgICJcblwwMzVGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGUiICsKICAgICAgImQ2NERvdWJsZTEwNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzJxXG5cMDM0RmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyQFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjEucHJvdG9idWYiICsKICAgICAgIi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW0iICsKICAgICAgIjpcMDAyOFwwMDFcMDMyQVxuXDAzN0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMkFcblwwMzdGaWVsZCIgKwogICAgICAiTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDY6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNmaXhlZDY0RmwiICsKICAgICAgIm9hdDEwOUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjoiICsKICAgICAgIlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTZml4ZWQ2NEludDMyMTEwRW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcCIgKwogICAgICAiU2ZpeGVkNjRJbnQ2NDExMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDAzOlwwMDI4XDAwMVwwMzJrXG5cMDM3RmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UiICsKICAgICAgIjExMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyN1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMigucCIgKwogICAgICAicm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8zTWVzc2FnZUxpdGU6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyQlxuIEZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJCXG4gRmllbGRNIiArCiAgICAgICJhcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMDpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ZpeGVkNjRTaSIgKwogICAgICAibnQzMjExNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMSIgKwogICAgICAiOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNIiArCiAgICAgICJhcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQ2NFVpbnQiICsKICAgICAgIjMyMTE4RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyIiArCiAgICAgICI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAyMFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXAiICsKICAgICAgIlNpbnQzMkJvb2wxMjBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZSIgKwogICAgICAibGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyIiArCiAgICAgICJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyb1xuXDAzMkZpZWxkTWFwU2ludDMyRW51bTEiICsKICAgICAgIjIzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJAXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyMS5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZSIgKwogICAgICAic3RFbnVtOlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGIiArCiAgICAgICJpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTaW50MzJGbCIgKwogICAgICAib2F0MTI2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOiIgKwogICAgICAiXDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpIiArCiAgICAgICJudDMySW50NjQxMjhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyaVxuXDAzNUZpZWxkTWFwU2ludDMyTWVzc2FnZTEyOUVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjI3XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyKC5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZTpcMDAyOFwwMDFcMDMyQFxuXDAzNiIgKwogICAgICAiRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTaW50MzIiICsKICAgICAgIlNmaXhlZDY0MTMxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIiICsKICAgICAgIiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbCIgKwogICAgICAiZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50MzJTdHJpbmciICsKICAgICAgIjEzNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDMyVWludDMyMTM1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50IiArCiAgICAgICIzMlVpbnQ2NDEzNkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBTaW50NjRCb29sMTM3RW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTA6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE0iICsKICAgICAgImFwU2ludDY0Qnl0ZXMxMzhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwU2ludDY0RG91YmxlMTM5IiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMm9cbiIgKwogICAgICAiXDAzMkZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjIiICsKICAgICAgIlwwMjJAXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyMS5wcm90b2J1Zi5leHBlcmltZW50YWwuIiArCiAgICAgICJQcm90bzNNZXNzYWdlTGl0ZS5UZXN0RW51bTpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTSIgKwogICAgICAiYXBTaW50NjRGaXhlZDMyMTQxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNSIgKwogICAgICAidmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFNpbnQ2NEZpeGVkNjQiICsKICAgICAgIjE0MkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI9XG5cMDMzRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTaW50NiIgKwogICAgICAiNEludDMyMTQ0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcMDIyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmlcblwwMzVGaWVsZE1hIiArCiAgICAgICJwU2ludDY0TWVzc2FnZTE0NkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyN1xuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyKC5wcm90b2J1Zi5leHBlcmltZW50YWwuUHJvdG8iICsKICAgICAgIjNNZXNzYWdlTGl0ZTpcMDAyOFwwMDFcMDMyQFxuXDAzNkZpZWxkTWFwU2ludDY0U2ZpeGVkIiArCiAgICAgICIzMjE0N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyIiArCiAgICAgICI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OEVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlNpbnQ2NFNpbnQzMjE0OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50NjRTaW50NjQxNTBFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAyMjpcMDAyOFwwMDFcMDMyPlxuXDAzNCIgKwogICAgICAiRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFNpbnQ2NFVpIiArCiAgICAgICJudDMyMTUyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcciIgKwogICAgICAiOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNDpcMDAyOFwwMDFcMDMyPFxuXDAzMkZpZWxkTWFwIiArCiAgICAgICJTdHJpbmdCb29sMTU0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZSIgKwogICAgICAiXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZSIgKwogICAgICAibGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcciIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMm9cblwwMzJGaWVsZE1hcFN0cmluZ0VudW0xIiArCiAgICAgICI1N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkBcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIxLnByIiArCiAgICAgICJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlLlRlIiArCiAgICAgICJzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE1hcFN0cmluZ0ZpeGVkMzIxNThFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGIiArCiAgICAgICJpZWxkTWFwU3RyaW5nRml4ZWQ2NDE1OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU3RyaW5nRmwiICsKICAgICAgIm9hdDE2MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDI6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFN0IiArCiAgICAgICJyaW5nSW50NjQxNjJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMCIgKwogICAgICAiXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmlcblwwMzVGaWVsZE1hcFN0cmluZ01lc3NhZ2UxNjNFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMjdcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIoLnByb3RvYnUiICsKICAgICAgImYuZXhwZXJpbWVudGFsLlByb3RvM01lc3NhZ2VMaXRlOlwwMDI4XDAwMVwwMzJAXG5cMDM2IiArCiAgICAgICJGaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxICIgKwogICAgICAiXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBTdHJpbmciICsKICAgICAgIlNmaXhlZDY0MTY1RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMjE6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsIiArCiAgICAgICJkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBTdHJpbmdTdHJpbmciICsKICAgICAgIjE2OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMSIgKwogICAgICAiXDAzMj5cblwwMzRGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFN0cmkiICsKICAgICAgIm5nVWludDY0MTcwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXBVaW50MzJCb29sMTcxRW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEwOlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNIiArCiAgICAgICJhcFVpbnQzMkJ5dGVzMTcyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50MzJEb3VibGUxNzMiICsKICAgICAgIkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDE6XDAwMjhcMDAxXDAzMm9cbiIgKwogICAgICAiXDAzMkZpZWxkTWFwVWludDMyRW51bTE3NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyIiArCiAgICAgICJcMDIyQFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjEucHJvdG9idWYuZXhwZXJpbWVudGFsLiIgKwogICAgICAiUHJvdG8zTWVzc2FnZUxpdGUuVGVzdEVudW06XDAwMjhcMDAxXDAzMj9cblwwMzVGaWVsZE0iICsKICAgICAgImFwVWludDMyRml4ZWQzMjE3NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1IiArCiAgICAgICJ2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDFcMDMyP1xuXDAzNUZpZWxkTWFwVWludDMyRml4ZWQ2NCIgKwogICAgICAiMTc2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI9XG5cMDMzRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMjpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMiICsKICAgICAgIjJJbnQzMjE3OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAwNTpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeVwwMjJcMDEzXG4iICsKICAgICAgIlwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDM6XDAwMjhcMDAxXDAzMmlcblwwMzVGaWVsZE1hIiArCiAgICAgICJwVWludDMyTWVzc2FnZTE4MEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMjdcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDEzMigucHJvdG9idWYuZXhwZXJpbWVudGFsLlByb3RvIiArCiAgICAgICIzTWVzc2FnZUxpdGU6XDAwMjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFVpbnQzMlNmaXhlZCIgKwogICAgICAiMzIxODFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDIiICsKICAgICAgIjhcMDAxXDAzMkBcblwwMzZGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXAiICsKICAgICAgIlVpbnQzMlNpbnQzMjE4M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyU2ludDY0MTg0RSIgKwogICAgICAibnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0IiArCiAgICAgICJGaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQzMlVpIiArCiAgICAgICJudDMyMTg2RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHIiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnlcMDIyXDAxM1xuXDAwMyIgKwogICAgICAia2V5XDAzMFwwMDEgXDAwMShcclwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI8XG5cMDMyRmllbGRNYXAiICsKICAgICAgIlVpbnQ2NEJvb2wxODhFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyPVxuXDAzM0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyPlxuXDAzNEZpZSIgKwogICAgICAibGRNYXBVaW50NjREb3VibGUxOTBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyIiArCiAgICAgICJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMTpcMDAyOFwwMDFcMDMyb1xuXDAzMkZpZWxkTWFwVWludDY0RW51bTEiICsKICAgICAgIjkxRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJAXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyMS5wciIgKwogICAgICAib3RvYnVmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZS5UZSIgKwogICAgICAic3RFbnVtOlwwMDI4XDAwMVwwMzI/XG5cMDM1RmllbGRNYXBVaW50NjRGaXhlZDMyMTkyRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDc6XDAwMjhcMDAxXDAzMj9cblwwMzVGIiArCiAgICAgICJpZWxkTWFwVWludDY0Rml4ZWQ2NDE5M0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA2OlwwMDI4XDAwMVwwMzI9XG5cMDMzRmllbGRNYXBVaW50NjRGbCIgKwogICAgICAib2F0MTk0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOiIgKwogICAgICAiXDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMj1cblwwMzNGaWVsZE1hcFVpIiArCiAgICAgICJudDY0SW50NjQxOTZFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyaVxuXDAzNUZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjI3XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyKC5wcm90b2J1IiArCiAgICAgICJmLmV4cGVyaW1lbnRhbC5Qcm90bzNNZXNzYWdlTGl0ZTpcMDAyOFwwMDFcMDMyQFxuXDAzNiIgKwogICAgICAiRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE3OlwwMDI4XDAwMVwwMzJAXG5cMDM2RmllbGRNYXBVaW50NjQiICsKICAgICAgIlNmaXhlZDY0MTk5RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIiICsKICAgICAgIiBcMDAxKFwwMjA6XDAwMjhcMDAxXDAzMj5cblwwMzRGaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIxOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbCIgKwogICAgICAiZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50NjRTdHJpbmciICsKICAgICAgIjIwMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyPlxuXDAzNEZpZWxkTWFwVWludDY0VWludDMyMjAzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDA0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzI+XG5cMDM0RmllbGRNYXBVaW50IiArCiAgICAgICI2NFVpbnQ2NDIwNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDA0OlwwMDI4XDAwMUIwXG5cMDMzY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nQiIgKwogICAgICAiXDAyMVByb3RvM1Rlc3RpbmdMaXRlYlwwMDZwcm90bzMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGREb3VibGUxIiwgIkZpZWxkRmxvYXQyIiwgIkZpZWxkSW50NjQzIiwgIkZpZWxkVWludDY0NCIsICJGaWVsZEludDMyNSIsICJGaWVsZEZpeGVkNjQ2IiwgIkZpZWxkRml4ZWQzMjciLCAiRmllbGRCb29sOCIsICJGaWVsZFN0cmluZzkiLCAiRmllbGRNZXNzYWdlMTAiLCAiRmllbGRCeXRlczExIiwgIkZpZWxkVWludDMyMTIiLCAiRmllbGRFbnVtMTMiLCAiRmllbGRTZml4ZWQzMjE0IiwgIkZpZWxkU2ZpeGVkNjQxNSIsICJGaWVsZFNpbnQzMjE2IiwgIkZpZWxkU2ludDY0MTciLCAiRmllbGREb3VibGVMaXN0MTgiLCAiRmllbGRGbG9hdExpc3QxOSIsICJGaWVsZEludDY0TGlzdDIwIiwgIkZpZWxkVWludDY0TGlzdDIxIiwgIkZpZWxkSW50MzJMaXN0MjIiLCAiRmllbGRGaXhlZDY0TGlzdDIzIiwgIkZpZWxkRml4ZWQzMkxpc3QyNCIsICJGaWVsZEJvb2xMaXN0MjUiLCAiRmllbGRTdHJpbmdMaXN0MjYiLCAiRmllbGRNZXNzYWdlTGlzdDI3IiwgIkZpZWxkQnl0ZXNMaXN0MjgiLCAiRmllbGRVaW50MzJMaXN0MjkiLCAiRmllbGRFbnVtTGlzdDMwIiwgIkZpZWxkU2ZpeGVkMzJMaXN0MzEiLCAiRmllbGRTZml4ZWQ2NExpc3QzMiIsICJGaWVsZFNpbnQzMkxpc3QzMyIsICJGaWVsZFNpbnQ2NExpc3QzNCIsICJGaWVsZERvdWJsZUxpc3RQYWNrZWQzNSIsICJGaWVsZEZsb2F0TGlzdFBhY2tlZDM2IiwgIkZpZWxkSW50NjRMaXN0UGFja2VkMzciLCAiRmllbGRVaW50NjRMaXN0UGFja2VkMzgiLCAiRmllbGRJbnQzMkxpc3RQYWNrZWQzOSIsICJGaWVsZEZpeGVkNjRMaXN0UGFja2VkNDAiLCAiRmllbGRGaXhlZDMyTGlzdFBhY2tlZDQxIiwgIkZpZWxkQm9vbExpc3RQYWNrZWQ0MiIsICJGaWVsZFVpbnQzMkxpc3RQYWNrZWQ0MyIsICJGaWVsZEVudW1MaXN0UGFja2VkNDQiLCAiRmllbGRTZml4ZWQzMkxpc3RQYWNrZWQ0NSIsICJGaWVsZFNmaXhlZDY0TGlzdFBhY2tlZDQ2IiwgIkZpZWxkU2ludDMyTGlzdFBhY2tlZDQ3IiwgIkZpZWxkU2ludDY0TGlzdFBhY2tlZDQ4IiwgIkZpZWxkRG91YmxlNTMiLCAiRmllbGRGbG9hdDU0IiwgIkZpZWxkSW50NjQ1NSIsICJGaWVsZFVpbnQ2NDU2IiwgIkZpZWxkSW50MzI1NyIsICJGaWVsZEZpeGVkNjQ1OCIsICJGaWVsZEZpeGVkMzI1OSIsICJGaWVsZEJvb2w2MCIsICJGaWVsZFN0cmluZzYxIiwgIkZpZWxkTWVzc2FnZTYyIiwgIkZpZWxkQnl0ZXM2MyIsICJGaWVsZFVpbnQzMjY0IiwgIkZpZWxkU2ZpeGVkMzI2NSIsICJGaWVsZFNmaXhlZDY0NjYiLCAiRmllbGRTaW50MzI2NyIsICJGaWVsZFNpbnQ2NDY4IiwgIlRlc3RPbmVvZiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNFbXB0eUxpdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM0VtcHR5TGl0ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zRW1wdHlMaXRlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZE1hcEJvb2xCb29sMSIsICJGaWVsZE1hcEJvb2xCeXRlczIiLCAiRmllbGRNYXBCb29sRG91YmxlMyIsICJGaWVsZE1hcEJvb2xFbnVtNCIsICJGaWVsZE1hcEJvb2xGaXhlZDMyNSIsICJGaWVsZE1hcEJvb2xGaXhlZDY0NiIsICJGaWVsZE1hcEJvb2xGbG9hdDciLCAiRmllbGRNYXBCb29sSW50MzI4IiwgIkZpZWxkTWFwQm9vbEludDY0OSIsICJGaWVsZE1hcEJvb2xNZXNzYWdlMTAiLCAiRmllbGRNYXBCb29sU2ZpeGVkMzIxMSIsICJGaWVsZE1hcEJvb2xTZml4ZWQ2NDEyIiwgIkZpZWxkTWFwQm9vbFNpbnQzMjEzIiwgIkZpZWxkTWFwQm9vbFNpbnQ2NDE0IiwgIkZpZWxkTWFwQm9vbFN0cmluZzE1IiwgIkZpZWxkTWFwQm9vbFVpbnQzMjE2IiwgIkZpZWxkTWFwQm9vbFVpbnQ2NDE3IiwgIkZpZWxkTWFwRml4ZWQzMkJvb2wxOCIsICJGaWVsZE1hcEZpeGVkMzJCeXRlczE5IiwgIkZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwIiwgIkZpZWxkTWFwRml4ZWQzMkVudW0yMSIsICJGaWVsZE1hcEZpeGVkMzJGaXhlZDMyMjIiLCAiRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzIiwgIkZpZWxkTWFwRml4ZWQzMkZsb2F0MjQiLCAiRmllbGRNYXBGaXhlZDMySW50MzIyNSIsICJGaWVsZE1hcEZpeGVkMzJJbnQ2NDI2IiwgIkZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyNyIsICJGaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4IiwgIkZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjkiLCAiRmllbGRNYXBGaXhlZDMyU2ludDMyMzAiLCAiRmllbGRNYXBGaXhlZDMyU2ludDY0MzEiLCAiRmllbGRNYXBGaXhlZDMyU3RyaW5nMzIiLCAiRmllbGRNYXBGaXhlZDMyVWludDMyMzMiLCAiRmllbGRNYXBGaXhlZDMyVWludDY0MzQiLCAiRmllbGRNYXBGaXhlZDY0Qm9vbDM1IiwgIkZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzYiLCAiRmllbGRNYXBGaXhlZDY0RG91YmxlMzciLCAiRmllbGRNYXBGaXhlZDY0RW51bTM4IiwgIkZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOSIsICJGaWVsZE1hcEZpeGVkNjRGaXhlZDY0NDAiLCAiRmllbGRNYXBGaXhlZDY0RmxvYXQ0MSIsICJGaWVsZE1hcEZpeGVkNjRJbnQzMjQyIiwgIkZpZWxkTWFwRml4ZWQ2NEludDY0NDMiLCAiRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0IiwgIkZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDUiLCAiRmllbGRNYXBGaXhlZDY0U2ZpeGVkNjQ0NiIsICJGaWVsZE1hcEZpeGVkNjRTaW50MzI0NyIsICJGaWVsZE1hcEZpeGVkNjRTaW50NjQ0OCIsICJGaWVsZE1hcEZpeGVkNjRTdHJpbmc0OSIsICJGaWVsZE1hcEZpeGVkNjRVaW50MzI1MCIsICJGaWVsZE1hcEZpeGVkNjRVaW50NjQ1MSIsICJGaWVsZE1hcEludDMyQm9vbDUyIiwgIkZpZWxkTWFwSW50MzJCeXRlczUzIiwgIkZpZWxkTWFwSW50MzJEb3VibGU1NCIsICJGaWVsZE1hcEludDMyRW51bTU1IiwgIkZpZWxkTWFwSW50MzJGaXhlZDMyNTYiLCAiRmllbGRNYXBJbnQzMkZpeGVkNjQ1NyIsICJGaWVsZE1hcEludDMyRmxvYXQ1OCIsICJGaWVsZE1hcEludDMySW50MzI1OSIsICJGaWVsZE1hcEludDMySW50NjQ2MCIsICJGaWVsZE1hcEludDMyTWVzc2FnZTYxIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQzMjYyIiwgIkZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzIiwgIkZpZWxkTWFwSW50MzJTaW50MzI2NCIsICJGaWVsZE1hcEludDMyU2ludDY0NjUiLCAiRmllbGRNYXBJbnQzMlN0cmluZzY2IiwgIkZpZWxkTWFwSW50MzJVaW50MzI2NyIsICJGaWVsZE1hcEludDMyVWludDY0NjgiLCAiRmllbGRNYXBJbnQ2NEJvb2w2OSIsICJGaWVsZE1hcEludDY0Qnl0ZXM3MCIsICJGaWVsZE1hcEludDY0RG91YmxlNzEiLCAiRmllbGRNYXBJbnQ2NEVudW03MiIsICJGaWVsZE1hcEludDY0Rml4ZWQzMjczIiwgIkZpZWxkTWFwSW50NjRGaXhlZDY0NzQiLCAiRmllbGRNYXBJbnQ2NEZsb2F0NzUiLCAiRmllbGRNYXBJbnQ2NEludDMyNzYiLCAiRmllbGRNYXBJbnQ2NEludDY0NzciLCAiRmllbGRNYXBJbnQ2NE1lc3NhZ2U3OCIsICJGaWVsZE1hcEludDY0U2ZpeGVkMzI3OSIsICJGaWVsZE1hcEludDY0U2ZpeGVkNjQ4MCIsICJGaWVsZE1hcEludDY0U2ludDMyODEiLCAiRmllbGRNYXBJbnQ2NFNpbnQ2NDgyIiwgIkZpZWxkTWFwSW50NjRTdHJpbmc4MyIsICJGaWVsZE1hcEludDY0VWludDMyODQiLCAiRmllbGRNYXBJbnQ2NFVpbnQ2NDg1IiwgIkZpZWxkTWFwU2ZpeGVkMzJCb29sODYiLCAiRmllbGRNYXBTZml4ZWQzMkJ5dGVzODciLCAiRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4IiwgIkZpZWxkTWFwU2ZpeGVkMzJFbnVtODkiLCAiRmllbGRNYXBTZml4ZWQzMkZpeGVkMzI5MCIsICJGaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxIiwgIkZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzIiwgIkZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0IiwgIkZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTUiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDMyOTYiLCAiRmllbGRNYXBTZml4ZWQzMlNmaXhlZDY0OTciLCAiRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4IiwgIkZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OSIsICJGaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwIiwgIkZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDEiLCAiRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMiIsICJGaWVsZE1hcFNmaXhlZDY0Qm9vbDEwMyIsICJGaWVsZE1hcFNmaXhlZDY0Qnl0ZXMxMDQiLCAiRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNSIsICJGaWVsZE1hcFNmaXhlZDY0RW51bTEwNiIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwNyIsICJGaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOCIsICJGaWVsZE1hcFNmaXhlZDY0RmxvYXQxMDkiLCAiRmllbGRNYXBTZml4ZWQ2NEludDMyMTEwIiwgIkZpZWxkTWFwU2ZpeGVkNjRJbnQ2NDExMSIsICJGaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMiIsICJGaWVsZE1hcFNmaXhlZDY0U2ZpeGVkMzIxMTMiLCAiRmllbGRNYXBTZml4ZWQ2NFNmaXhlZDY0MTE0IiwgIkZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTUiLCAiRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNiIsICJGaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3IiwgIkZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMTgiLCAiRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOSIsICJGaWVsZE1hcFNpbnQzMkJvb2wxMjAiLCAiRmllbGRNYXBTaW50MzJCeXRlczEyMSIsICJGaWVsZE1hcFNpbnQzMkRvdWJsZTEyMiIsICJGaWVsZE1hcFNpbnQzMkVudW0xMjMiLCAiRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0IiwgIkZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNSIsICJGaWVsZE1hcFNpbnQzMkZsb2F0MTI2IiwgIkZpZWxkTWFwU2ludDMySW50MzIxMjciLCAiRmllbGRNYXBTaW50MzJJbnQ2NDEyOCIsICJGaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjkiLCAiRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMCIsICJGaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxIiwgIkZpZWxkTWFwU2ludDMyU2ludDMyMTMyIiwgIkZpZWxkTWFwU2ludDMyU2ludDY0MTMzIiwgIkZpZWxkTWFwU2ludDMyU3RyaW5nMTM0IiwgIkZpZWxkTWFwU2ludDMyVWludDMyMTM1IiwgIkZpZWxkTWFwU2ludDMyVWludDY0MTM2IiwgIkZpZWxkTWFwU2ludDY0Qm9vbDEzNyIsICJGaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4IiwgIkZpZWxkTWFwU2ludDY0RG91YmxlMTM5IiwgIkZpZWxkTWFwU2ludDY0RW51bTE0MCIsICJGaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDEiLCAiRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyIiwgIkZpZWxkTWFwU2ludDY0RmxvYXQxNDMiLCAiRmllbGRNYXBTaW50NjRJbnQzMjE0NCIsICJGaWVsZE1hcFNpbnQ2NEludDY0MTQ1IiwgIkZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NiIsICJGaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3IiwgIkZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDgiLCAiRmllbGRNYXBTaW50NjRTaW50MzIxNDkiLCAiRmllbGRNYXBTaW50NjRTaW50NjQxNTAiLCAiRmllbGRNYXBTaW50NjRTdHJpbmcxNTEiLCAiRmllbGRNYXBTaW50NjRVaW50MzIxNTIiLCAiRmllbGRNYXBTaW50NjRVaW50NjQxNTMiLCAiRmllbGRNYXBTdHJpbmdCb29sMTU0IiwgIkZpZWxkTWFwU3RyaW5nQnl0ZXMxNTUiLCAiRmllbGRNYXBTdHJpbmdEb3VibGUxNTYiLCAiRmllbGRNYXBTdHJpbmdFbnVtMTU3IiwgIkZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OCIsICJGaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTkiLCAiRmllbGRNYXBTdHJpbmdGbG9hdDE2MCIsICJGaWVsZE1hcFN0cmluZ0ludDMyMTYxIiwgIkZpZWxkTWFwU3RyaW5nSW50NjQxNjIiLCAiRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzIiwgIkZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjQiLCAiRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NSIsICJGaWVsZE1hcFN0cmluZ1NpbnQzMjE2NiIsICJGaWVsZE1hcFN0cmluZ1NpbnQ2NDE2NyIsICJGaWVsZE1hcFN0cmluZ1N0cmluZzE2OCIsICJGaWVsZE1hcFN0cmluZ1VpbnQzMjE2OSIsICJGaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MCIsICJGaWVsZE1hcFVpbnQzMkJvb2wxNzEiLCAiRmllbGRNYXBVaW50MzJCeXRlczE3MiIsICJGaWVsZE1hcFVpbnQzMkRvdWJsZTE3MyIsICJGaWVsZE1hcFVpbnQzMkVudW0xNzQiLCAiRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1IiwgIkZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NiIsICJGaWVsZE1hcFVpbnQzMkZsb2F0MTc3IiwgIkZpZWxkTWFwVWludDMySW50MzIxNzgiLCAiRmllbGRNYXBVaW50MzJJbnQ2NDE3OSIsICJGaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODAiLCAiRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MSIsICJGaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyIiwgIkZpZWxkTWFwVWludDMyU2ludDMyMTgzIiwgIkZpZWxkTWFwVWludDMyU2ludDY0MTg0IiwgIkZpZWxkTWFwVWludDMyU3RyaW5nMTg1IiwgIkZpZWxkTWFwVWludDMyVWludDMyMTg2IiwgIkZpZWxkTWFwVWludDMyVWludDY0MTg3IiwgIkZpZWxkTWFwVWludDY0Qm9vbDE4OCIsICJGaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5IiwgIkZpZWxkTWFwVWludDY0RG91YmxlMTkwIiwgIkZpZWxkTWFwVWludDY0RW51bTE5MSIsICJGaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTIiLCAiRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzIiwgIkZpZWxkTWFwVWludDY0RmxvYXQxOTQiLCAiRmllbGRNYXBVaW50NjRJbnQzMjE5NSIsICJGaWVsZE1hcFVpbnQ2NEludDY0MTk2IiwgIkZpZWxkTWFwVWludDY0TWVzc2FnZTE5NyIsICJGaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4IiwgIkZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTkiLCAiRmllbGRNYXBVaW50NjRTaW50MzIyMDAiLCAiRmllbGRNYXBVaW50NjRTaW50NjQyMDEiLCAiRmllbGRNYXBVaW50NjRTdHJpbmcyMDIiLCAiRmllbGRNYXBVaW50NjRVaW50MzIyMDMiLCAiRmllbGRNYXBVaW50NjRVaW50NjQyMDQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCb29sMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJvb2wxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEJ5dGVzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xCeXRlczJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xEb3VibGUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRG91YmxlM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xFbnVtNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEVudW00RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEZpeGVkMzI1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQzMjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRml4ZWQ2NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGaXhlZDY0NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xGbG9hdDdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sRmxvYXQ3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDMyOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xJbnQzMjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sSW50NjQ5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbEludDY0OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xNZXNzYWdlMTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBCb29sTWVzc2FnZTEwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDMyMTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQzMjExRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNmaXhlZDY0MTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTZml4ZWQ2NDEyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQzMjEzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50MzIxM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQzMjEzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTaW50NjQxNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFNpbnQ2NDE0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xTdHJpbmcxNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFN0cmluZzE1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQzMjE2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50MzIxNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQzMjE2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEJvb2xVaW50NjQxN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwQm9vbFVpbnQ2NDE3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJvb2wxOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyQm9vbDE4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkJ5dGVzMTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJCeXRlczE5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJEb3VibGUyMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkRvdWJsZTIwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkVudW0yMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRW51bTIxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkMzIyMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQzMjIyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZpeGVkNjQyM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyRml4ZWQ2NDIzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkZsb2F0MjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJGbG9hdDI0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDMyMjVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQzMjI1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMkludDY0MjZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJJbnQ2NDI2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMk1lc3NhZ2UyN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDMyTWVzc2FnZTI3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDMyMjhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQzMjI4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNmaXhlZDY0MjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTZml4ZWQ2NDI5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDI5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50MzIzMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQzMjMwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTaW50NjQzMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlNpbnQ2NDMxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJTdHJpbmczMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlN0cmluZzMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50MzIzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQzMjMzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkMzJVaW50NjQzNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQzMlVpbnQ2NDM0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJvb2wzNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Qm9vbDM1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMzUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEJ5dGVzMzZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRCeXRlczM2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDM2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjREb3VibGUzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NERvdWJsZTM3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEVudW0zOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RW51bTM4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0RW51bTM4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkMzIzOUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQzMjM5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZpeGVkNjQ0MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzOSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0Rml4ZWQ2NDQwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEZsb2F0NDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRGbG9hdDQxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDMyNDJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQzMjQyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NEludDY0NDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRJbnQ2NDQzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NE1lc3NhZ2U0NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBGaXhlZDY0TWVzc2FnZTQ0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDMyNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQzMjQ1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNmaXhlZDY0NDZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTZml4ZWQ2NDQ2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50MzI0N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQzMjQ3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTaW50NjQ0OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFNpbnQ2NDQ4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRTdHJpbmc0OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFN0cmluZzQ5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQ5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50MzI1MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQzMjUwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEZpeGVkNjRVaW50NjQ1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwRml4ZWQ2NFVpbnQ2NDUxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCb29sNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQm9vbDUyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyQnl0ZXM1M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJCeXRlczUzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJEb3VibGU1NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMkRvdWJsZTU0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJFbnVtNTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRW51bTU1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDMyNTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQzMjU2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGaXhlZDY0NTdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRml4ZWQ2NDU3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGbG9hdDU4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyRmxvYXQ1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJGbG9hdDU4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50MzI1OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQzMjU5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDU5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMySW50NjQ2MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJJbnQ2NDYwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJNZXNzYWdlNjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyTWVzc2FnZTYxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkMzI2MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQzMjYyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDMyU2ZpeGVkNjQ2M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTZml4ZWQ2NDYzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50MzI2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQzMjY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTaW50NjQ2NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQ2NDY1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlNpbnQ2NDY1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJTdHJpbmc2NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlN0cmluZzY2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50MzI2N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQzMjY3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50MzJVaW50NjQ2OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQ2NDY4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQzMlVpbnQ2NDY4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNjgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCb29sNjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qm9vbDY5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCeXRlczcwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDY5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Qnl0ZXM3MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRCeXRlczcwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjREb3VibGU3MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NERvdWJsZTcxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NERvdWJsZTcxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRFbnVtNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RW51bTcyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDMyNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQzMjczRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGaXhlZDY0NzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0Rml4ZWQ2NDc0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0RmxvYXQ3NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRGbG9hdDc1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50MzI3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQzMjc2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0SW50NjQ3N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRJbnQ2NDc3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNzcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRNZXNzYWdlNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0TWVzc2FnZTc4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkMzI3OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQzMjc5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDc5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcEludDY0U2ZpeGVkNjQ4MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTZml4ZWQ2NDgwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50MzI4MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQzMjgxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTaW50NjQ4MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFNpbnQ2NDgyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRTdHJpbmc4M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFN0cmluZzgzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50MzI4NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQzMjg0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwSW50NjRVaW50NjQ4NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBJbnQ2NFVpbnQ2NDg1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCb29sODZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQm9vbDg2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyQnl0ZXM4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJCeXRlczg3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJEb3VibGU4OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMkRvdWJsZTg4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJFbnVtODlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRW51bTg5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoODkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDMyOTBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQzMjkwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGaXhlZDY0OTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRml4ZWQ2NDkxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyRmxvYXQ5MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJGbG9hdDkyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50MzI5M0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQzMjkzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMySW50NjQ5NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJJbnQ2NDk0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJNZXNzYWdlOTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyTWVzc2FnZTk1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkMzI5NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQzMjk2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDk2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU2ZpeGVkNjQ5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTZml4ZWQ2NDk3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50MzI5OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQzMjk4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTaW50NjQ5OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlNpbnQ2NDk5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJTdHJpbmcxMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyU3RyaW5nMTAwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50MzIxMDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDMyMTAxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQzMjEwMUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDMyVWludDY0MTAyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQzMlVpbnQ2NDEwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkMzJVaW50NjQxMDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEJvb2wxMDNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTAyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Qm9vbDEwM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCb29sMTAzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRCeXRlczEwNEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RG91YmxlMTA1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NERvdWJsZTEwNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjREb3VibGUxMDVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEVudW0xMDZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTA1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0RW51bTEwNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRFbnVtMTA2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDMyMTA3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkMzIxMDdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQzMjEwN0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0Rml4ZWQ2NDEwOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRGaXhlZDY0MTA4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZpeGVkNjQxMDhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NEZsb2F0MTA5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRJbnQzMjExMEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0SW50NjQxMTFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NE1lc3NhZ2UxMTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTExKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0TWVzc2FnZTExMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRNZXNzYWdlMTEyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTZml4ZWQzMjExM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ZpeGVkNjQxMTRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQzMjExNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50MzIxMTVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDMyMTE1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTaW50NjQxMTZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U2ludDY0MTE2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFNpbnQ2NDExNkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0U3RyaW5nMTE3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDExNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFN0cmluZzExN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRTdHJpbmcxMTdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQzMjExOEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50MzIxMThFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDMyMTE4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ZpeGVkNjRVaW50NjQxMTlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNmaXhlZDY0VWludDY0MTE5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTZml4ZWQ2NFVpbnQ2NDExOUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTE5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJvb2wxMjBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJCeXRlczEyMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyQnl0ZXMxMjFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkJ5dGVzMTIxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRG91YmxlMTIyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJEb3VibGUxMjJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkRvdWJsZTEyMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTIyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkVudW0xMjNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGaXhlZDMyMTI0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRml4ZWQ2NDEyNUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkZsb2F0MTI2RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJGbG9hdDEyNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyRmxvYXQxMjZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQzMjEyN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50MzIxMjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDMyMTI3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMySW50NjQxMjhFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMkludDY0MTI4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJJbnQ2NDEyOEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTI4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMk1lc3NhZ2UxMjlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQzMjEzMEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMjkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkMzIxMzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDMyMTMwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ZpeGVkNjQxMzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTMwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNmaXhlZDY0MTMxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTZml4ZWQ2NDEzMUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQzMjEzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDMyMTMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50MzIxMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTaW50NjQxMzNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTMyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlNpbnQ2NDEzM0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU2ludDY0MTMzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyU3RyaW5nMTM0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJTdHJpbmcxMzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlN0cmluZzEzNEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQzMjEzNUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDMyMTM1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50MzIxMzVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50MzJVaW50NjQxMzZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTM1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQzMlVpbnQ2NDEzNkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDMyVWludDY0MTM2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qm9vbDEzN0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEJ5dGVzMTM4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRCeXRlczEzOEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0Qnl0ZXMxMzhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjREb3VibGUxMzlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTM4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NERvdWJsZTEzOUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RG91YmxlMTM5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RW51bTE0MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZpeGVkMzIxNDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGaXhlZDY0MTQyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0RmxvYXQxNDNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEZsb2F0MTQzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRGbG9hdDE0M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDMyMTQ0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQzMjE0NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50MzIxNDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRJbnQ2NDE0NUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0SW50NjQxNDVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NEludDY0MTQ1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0TWVzc2FnZTE0NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDMyMTQ3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQzMjE0N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkMzIxNDdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTZml4ZWQ2NDE0OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ZpeGVkNjQxNDhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNmaXhlZDY0MTQ4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDMyMTQ5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50MzIxNDlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQzMjE0OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFNpbnQ2NDE1MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U2ludDY0MTUwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTaW50NjQxNTBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRTdHJpbmcxNTFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTUwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFN0cmluZzE1MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0U3RyaW5nMTUxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDMyMTUyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50MzIxNTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQzMjE1MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFNpbnQ2NFVpbnQ2NDE1M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU2ludDY0VWludDY0MTUzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTaW50NjRVaW50NjQxNTNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1Myk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCb29sMTU0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nQnl0ZXMxNTVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0J5dGVzMTU1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdCeXRlczE1NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0RvdWJsZTE1NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRG91YmxlMTU2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdEb3VibGUxNTZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdFbnVtMTU3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRml4ZWQzMjE1OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTU4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ZpeGVkNjQxNTlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdGbG9hdDE2MEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nRmxvYXQxNjBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0Zsb2F0MTYwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50MzIxNjFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDMyMTYxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQzMjE2MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ0ludDY0MTYyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdJbnQ2NDE2MkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nSW50NjQxNjJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdNZXNzYWdlMTYzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkMzIxNjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDMyMTY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQzMjE2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NmaXhlZDY0MTY1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTZml4ZWQ2NDE2NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ZpeGVkNjQxNjVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50MzIxNjZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTY1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQzMjE2NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDMyMTY2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU2ludDY0MTY3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTaW50NjQxNjdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1NpbnQ2NDE2N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1N0cmluZzE2OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNjcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nU3RyaW5nMTY4RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdTdHJpbmcxNjhFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50MzIxNjlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTY4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQzMjE2OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDMyMTY5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwU3RyaW5nVWludDY0MTcwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBTdHJpbmdVaW50NjQxNzBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFN0cmluZ1VpbnQ2NDE3MEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTcwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJvb2wxNzFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJCeXRlczE3MkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyQnl0ZXMxNzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkJ5dGVzMTcyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRG91YmxlMTczRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJEb3VibGUxNzNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkRvdWJsZTE3M0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTczKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkVudW0xNzRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGaXhlZDMyMTc1RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRml4ZWQ2NDE3NkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkZsb2F0MTc3RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE3Nik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJGbG9hdDE3N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyRmxvYXQxNzdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQzMjE3OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNzcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50MzIxNzhFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDMyMTc4RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMySW50NjQxNzlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMkludDY0MTc5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJJbnQ2NDE3OUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTc5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMk1lc3NhZ2UxODBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQzMjE4MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkMzIxODFFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDMyMTgxRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ZpeGVkNjQxODJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNmaXhlZDY0MTgyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTZml4ZWQ2NDE4MkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQzMjE4M0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDMyMTgzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50MzIxODNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTaW50NjQxODRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlNpbnQ2NDE4NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU2ludDY0MTg0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyU3RyaW5nMTg1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJTdHJpbmcxODVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlN0cmluZzE4NUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQzMjE4NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDMyMTg2RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50MzIxODZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50MzJVaW50NjQxODdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQzMlVpbnQ2NDE4N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDMyVWludDY0MTg3RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxODcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qm9vbDE4OEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEJ5dGVzMTg5RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRCeXRlczE4OUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0Qnl0ZXMxODlFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjREb3VibGUxOTBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTg5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NERvdWJsZTE5MEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RG91YmxlMTkwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RW51bTE5MUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RW51bTE5MUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RW51bTE5MUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTkxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZpeGVkMzIxOTJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGaXhlZDY0MTkzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0RmxvYXQxOTRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTkzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEZsb2F0MTk0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRGbG9hdDE5NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDMyMTk1RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQzMjE5NUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50MzIxOTVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRJbnQ2NDE5NkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0SW50NjQxOTZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NEludDY0MTk2RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0TWVzc2FnZTE5N0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDMyMTk4RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQzMjE5OEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkMzIxOThFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTZml4ZWQ2NDE5OUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxOTgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ZpeGVkNjQxOTlFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNmaXhlZDY0MTk5RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDMyMjAwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE5OSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50MzIyMDBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQzMjIwMEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFNpbnQ2NDIwMUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U2ludDY0MjAxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTaW50NjQyMDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRTdHJpbmcyMDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMjAxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFN0cmluZzIwMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0U3RyaW5nMjAyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDMyMjAzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIwMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50MzIyMDNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQzMjIwM0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl9leHBlcmltZW50YWxfUHJvdG8zTWVzc2FnZUxpdGVXaXRoTWFwc19GaWVsZE1hcFVpbnQ2NFVpbnQ2NDIwNEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyMDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX2V4cGVyaW1lbnRhbF9Qcm90bzNNZXNzYWdlTGl0ZVdpdGhNYXBzX0ZpZWxkTWFwVWludDY0VWludDY0MjA0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfZXhwZXJpbWVudGFsX1Byb3RvM01lc3NhZ2VMaXRlV2l0aE1hcHNfRmllbGRNYXBVaW50NjRVaW50NjQyMDRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQBbasWFvjUBAL41AQBfAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3RleHRmb3JtYXQvcGVyZm9ybWFuY2UvcHJvdG8yL1Byb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8yX3RleHRfZm9ybWF0X3BlcmZvcm1hbmNlX3Rlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMjsKCnB1YmxpYyBmaW5hbCBjbGFzcyBQcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90byB7CiAgcHJpdmF0ZSBQcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uc3ViTXNnRXh0KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBDb250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Yk1zZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViTXNnKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViTXNnLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBnZXRTdWJNc2coKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIGdldFN1Yk1zZ09yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMikKICAgICAgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCX01TR19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBzdWJNc2dfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTXNnIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTXNnKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViTXNnLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgZ2V0U3ViTXNnKCkgewogICAgICByZXR1cm4gc3ViTXNnXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNc2dfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIGdldFN1Yk1zZ09yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHN1Yk1zZ18gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTXNnXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0U3ViTXNnKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0U3ViTXNnKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMikgb2JqOwoKICAgICAgaWYgKGhhc1N1Yk1zZygpICE9IG90aGVyLmhhc1N1Yk1zZygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdWJNc2coKSkgewogICAgICAgIGlmICghZ2V0U3ViTXNnKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdWJNc2coKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNTdWJNc2coKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNVQl9NU0dfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN1Yk1zZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX0NvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMi5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldFN1Yk1zZ0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc3ViTXNnXyA9IG51bGw7CiAgICAgICAgaWYgKHN1Yk1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1Yk1zZ0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1Yk1zZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3ViTXNnXyA9IHN1Yk1zZ0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IHN1Yk1zZ18KICAgICAgICAgICAgICA6IHN1Yk1zZ0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzU3ViTXNnKCkpIHsKICAgICAgICAgIG1lcmdlU3ViTXNnKG90aGVyLmdldFN1Yk1zZygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0U3ViTXNnRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHN1Yk1zZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMk9yQnVpbGRlcj4gc3ViTXNnQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWJNc2cgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTXNnKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Yk1zZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBnZXRTdWJNc2coKSB7CiAgICAgICAgaWYgKHN1Yk1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJNc2dfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1zZ187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJNc2dCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1zZyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiB2YWx1ZSkgewogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHN1Yk1zZ18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTXNnQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJNc2coCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJNc2dfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Yk1zZ0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VTdWJNc2coY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgdmFsdWUpIHsKICAgICAgICBpZiAoc3ViTXNnQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIHN1Yk1zZ18gIT0gbnVsbCAmJgogICAgICAgICAgICBzdWJNc2dfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFN1Yk1zZ0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViTXNnXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoc3ViTXNnXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdWJNc2coKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHN1Yk1zZ18gPSBudWxsOwogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyIGdldFN1Yk1zZ0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRTdWJNc2dGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIGdldFN1Yk1zZ09yQnVpbGRlcigpIHsKICAgICAgICBpZiAoc3ViTXNnQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHN1Yk1zZ0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1Yk1zZ18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNc2dfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzJPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0U3ViTXNnRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFN1Yk1zZygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgc3ViTXNnXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdWJNc2dCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBDb250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBSZXBlYXRlZEludDMyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB2YWx1ZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdmFsdWUuCiAgICAgKi8KICAgIGludCBnZXRWYWx1ZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFZhbHVlKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlcGVhdGVkSW50MzIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyKQogICAgICBSZXBlYXRlZEludDMyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBSZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFJlcGVhdGVkSW50MzIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBSZXBlYXRlZEludDMyKCkgewogICAgICB2YWx1ZV8gPSBlbXB0eUludExpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEludDMyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX1JlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCB2YWx1ZV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRWYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiB2YWx1ZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRWYWx1ZUNvdW50KCkgewogICAgICByZXR1cm4gdmFsdWVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdmFsdWUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gdmFsdWVfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIHZhbHVlXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHZhbHVlXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFZhbHVlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIpIG9iajsKCiAgICAgIGlmICghZ2V0VmFsdWVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VmFsdWVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFZhbHVlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlJlcGVhdGVkSW50MzIpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX1JlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX1JlcGVhdGVkSW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHZhbHVlXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfUmVwZWF0ZWRJbnQzMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICB2YWx1ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnZhbHVlXyA9IHZhbHVlXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIudmFsdWVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHZhbHVlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgdmFsdWVfID0gb3RoZXIudmFsdWVfOwogICAgICAgICAgICB2YWx1ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgICB2YWx1ZV8uYWRkQWxsKG90aGVyLnZhbHVlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVZhbHVlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB2YWx1ZV8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICB2YWx1ZV8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCB2YWx1ZV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVZhbHVlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghdmFsdWVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB2YWx1ZV8gPSBtYWtlTXV0YWJsZUNvcHkodmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFZhbHVlTGlzdCgpIHsKICAgICAgICB2YWx1ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRWYWx1ZUNvdW50KCkgewogICAgICAgIHJldHVybiB2YWx1ZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRWYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdmFsdWVfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVmFsdWVJc011dGFibGUoKTsKICAgICAgICB2YWx1ZV8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVmFsdWUoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVZhbHVlSXNNdXRhYmxlKCk7CiAgICAgICAgdmFsdWVfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSB2YWx1ZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVmFsdWVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdmFsdWVfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgdmFsdWVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRJbnQzMj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZXBlYXRlZEludDMyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUmVwZWF0ZWRJbnQzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcGVhdGVkSW50MzI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRJbnQzMj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBDb250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8Q29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlPiB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UpCiAgICAgIENvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIENvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBDb250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX0NvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2U+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX0NvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSwgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPENvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIENvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDb250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMi5Qcm90bzJUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCX01TR19FWFRfRklFTERfTlVNQkVSID0gMTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzIuQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zRXh0ZW5zaW9uU3ViTWVzc2FnZSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzI+IHN1Yk1zZ0V4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuY2xhc3MsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8yLlByb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9SZXBlYXRlZEludDMyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbj1jb20vZ29vZ2xlL3Byb3RvYnVmL3Byb3RvMl90ZXh0X2Zvcm1hdCIgKwogICAgICAiX3BlcmZvcm1hbmNlX3Rlc3QucHJvdG9cMDIyLnByb3RvYnVmLnRlc3RpbiIgKwogICAgICAiZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMlwidVxuI0NvbnRhIiArCiAgICAgICJpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJcMDIyTlxuXDAwN3N1Yl9tcyIgKwogICAgICAiZ1wwMzBcMDAxIFwwMDEoXDAxMzI9LnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZSIgKwogICAgICAicmZvcm1hbmNlLnByb3RvMi5SZXBlYXRlZEludDMyXCJcMDM2XG5cclJlcGVhdCIgKwogICAgICAiZWRJbnQzMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMyhcMDA1XCJcJ1xuXDAzM0NvbnRhaW5zRXh0ZW5zIiArCiAgICAgICJpb25TdWJNZXNzYWdlKlwwMTBcMDEwXDAwMVwwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMjpcMjM3XDAwMVxuXDAxM3N1Yl9tc2dfZXh0XDAyMiIgKwogICAgICAiSy5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuYyIgKwogICAgICAiZS5wcm90bzIuQ29udGFpbnNFeHRlbnNpb25TdWJNZXNzYWdlXDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMTMyPS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybSIgKwogICAgICAiYW5jZS5wcm90bzIuUmVwZWF0ZWRJbnQzMkJdXG45Y29tLmdvb2dsZS4iICsKICAgICAgInByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS4iICsKICAgICAgInByb3RvMkIgUHJvdG8yVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8iCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX0NvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiU3ViTXNnIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9SZXBlYXRlZEludDMyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzJfUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8yX1JlcGVhdGVkSW50MzJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvMl9Db250YWluc0V4dGVuc2lvblN1Yk1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBzdWJNc2dFeHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQDCM/2NFtwAABbcAABfAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3RleHRmb3JtYXQvcGVyZm9ybWFuY2UvcHJvdG8zL1Byb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8zX3RleHRfZm9ybWF0X3BlcmZvcm1hbmNlX3Rlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMzsKCnB1YmxpYyBmaW5hbCBjbGFzcyBQcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90byB7CiAgcHJpdmF0ZSBQcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBDb250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Yk1zZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViTXNnKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViTXNnLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBnZXRTdWJNc2coKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIGdldFN1Yk1zZ09yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMikKICAgICAgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCX01TR19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBzdWJNc2dfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTXNnIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTXNnKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViTXNnLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgZ2V0U3ViTXNnKCkgewogICAgICByZXR1cm4gc3ViTXNnXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNc2dfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIGdldFN1Yk1zZ09yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHN1Yk1zZ18gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTXNnXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0U3ViTXNnKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0U3ViTXNnKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMikgb2JqOwoKICAgICAgaWYgKGhhc1N1Yk1zZygpICE9IG90aGVyLmhhc1N1Yk1zZygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdWJNc2coKSkgewogICAgICAgIGlmICghZ2V0U3ViTXNnKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdWJNc2coKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNTdWJNc2coKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNVQl9NU0dfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN1Yk1zZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8zX0NvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMi5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldFN1Yk1zZ0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc3ViTXNnXyA9IG51bGw7CiAgICAgICAgaWYgKHN1Yk1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1Yk1zZ0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1Yk1zZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3ViTXNnXyA9IHN1Yk1zZ0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IHN1Yk1zZ18KICAgICAgICAgICAgICA6IHN1Yk1zZ0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzU3ViTXNnKCkpIHsKICAgICAgICAgIG1lcmdlU3ViTXNnKG90aGVyLmdldFN1Yk1zZygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0U3ViTXNnRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHN1Yk1zZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMk9yQnVpbGRlcj4gc3ViTXNnQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWJNc2cgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTXNnKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Yk1zZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBnZXRTdWJNc2coKSB7CiAgICAgICAgaWYgKHN1Yk1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJNc2dfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1zZ187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJNc2dCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1zZyhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiB2YWx1ZSkgewogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHN1Yk1zZ18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTXNnQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJNc2coCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJNc2dfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Yk1zZ0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VTdWJNc2coY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgdmFsdWUpIHsKICAgICAgICBpZiAoc3ViTXNnQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIHN1Yk1zZ18gIT0gbnVsbCAmJgogICAgICAgICAgICBzdWJNc2dfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFN1Yk1zZ0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViTXNnXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoc3ViTXNnXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdWJNc2coKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHN1Yk1zZ18gPSBudWxsOwogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyIHN1Yl9tc2cgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyIGdldFN1Yk1zZ0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRTdWJNc2dGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlJlcGVhdGVkSW50MzIgc3ViX21zZyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIGdldFN1Yk1zZ09yQnVpbGRlcigpIHsKICAgICAgICBpZiAoc3ViTXNnQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHN1Yk1zZ0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1Yk1zZ18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNc2dfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMiBzdWJfbXNnID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzJPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0U3ViTXNnRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJNc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJNc2dCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFN1Yk1zZygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgc3ViTXNnXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdWJNc2dCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLkNvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBDb250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBSZXBlYXRlZEludDMyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB2YWx1ZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdmFsdWUuCiAgICAgKi8KICAgIGludCBnZXRWYWx1ZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFZhbHVlKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlcGVhdGVkSW50MzIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyKQogICAgICBSZXBlYXRlZEludDMyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBSZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFJlcGVhdGVkSW50MzIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBSZXBlYXRlZEludDMyKCkgewogICAgICB2YWx1ZV8gPSBlbXB0eUludExpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEludDMyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8zX1JlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCB2YWx1ZV8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRWYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiB2YWx1ZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRWYWx1ZUNvdW50KCkgewogICAgICByZXR1cm4gdmFsdWVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdmFsdWUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gdmFsdWVfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCB2YWx1ZU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmIChnZXRWYWx1ZUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHZhbHVlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHZhbHVlXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHZhbHVlXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0VmFsdWVMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDE7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgdmFsdWVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyKSBvYmo7CgogICAgICBpZiAoIWdldFZhbHVlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFZhbHVlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRWYWx1ZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFZhbHVlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMyKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19SZXBlYXRlZEludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19SZXBlYXRlZEludDMyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICB2YWx1ZV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8zX1JlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgdmFsdWVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlByb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLlJlcGVhdGVkSW50MzIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnZhbHVlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh2YWx1ZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHZhbHVlXyA9IG90aGVyLnZhbHVlXzsKICAgICAgICAgICAgdmFsdWVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVmFsdWVJc011dGFibGUoKTsKICAgICAgICAgICAgdmFsdWVfLmFkZEFsbChvdGhlci52YWx1ZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdmFsdWVfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlVmFsdWVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgdmFsdWVfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgdmFsdWVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVWYWx1ZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXZhbHVlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdmFsdWVfID0gbWFrZU11dGFibGVDb3B5KHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRWYWx1ZUxpc3QoKSB7CiAgICAgICAgdmFsdWVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWVDb3VudCgpIHsKICAgICAgICByZXR1cm4gdmFsdWVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHZhbHVlXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVZhbHVlSXNNdXRhYmxlKCk7CiAgICAgICAgdmFsdWVfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFZhbHVlKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgIHZhbHVlXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdmFsdWUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVZhbHVlSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHZhbHVlXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgIHZhbHVlXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zi50ZXN0aW5nLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zLlJlcGVhdGVkSW50MzIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUmVwZWF0ZWRJbnQzMikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wZXJmb3JtYW5jZS5wcm90bzMuUHJvdG8zVGV4dEZvcm1hdFBlcmZvcm1hbmNlUHJvdG8uUmVwZWF0ZWRJbnQzMiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcGVhdGVkSW50MzI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UmVwZWF0ZWRJbnQzMj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFJlcGVhdGVkSW50MzIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZEludDMyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcGVhdGVkSW50MzI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy50ZXh0Zm9ybWF0LnBlcmZvcm1hbmNlLnByb3RvMy5Qcm90bzNUZXh0Rm9ybWF0UGVyZm9ybWFuY2VQcm90by5SZXBlYXRlZEludDMyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19SZXBlYXRlZEludDMyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfUmVwZWF0ZWRJbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuPWNvbS9nb29nbGUvcHJvdG9idWYvcHJvdG8zX3RleHRfZm9ybWF0IiArCiAgICAgICJfcGVyZm9ybWFuY2VfdGVzdC5wcm90b1wwMjIucHJvdG9idWYudGVzdGluIiArCiAgICAgICJnLnRleHRmb3JtYXQucGVyZm9ybWFuY2UucHJvdG8zXCJcMjA2XDAwMVxuI0NvbnQiICsKICAgICAgImFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJcMDIyU1xuXDAwN3N1Yl9tIiArCiAgICAgICJzZ1wwMzBcMDAxIFwwMDEoXDAxMzI9LnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm1hdC5wIiArCiAgICAgICJlcmZvcm1hbmNlLnByb3RvMy5SZXBlYXRlZEludDMySFwwMDBcMjEwXDAwMVwwMDFCXG5cblwwMTAiICsKICAgICAgIl9zdWJfbXNnXCJcMDM2XG5cclJlcGVhdGVkSW50MzJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDMoXDAwNSIgKwogICAgICAiQl1cbjljb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcudGV4dGZvcm0iICsKICAgICAgImF0LnBlcmZvcm1hbmNlLnByb3RvM0IgUHJvdG8zVGV4dEZvcm1hdFAiICsKICAgICAgImVyZm9ybWFuY2VQcm90b2JcMDA2cHJvdG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19Db250YWluc1N1Yk1lc3NhZ2VXaXRoUmVwZWF0ZWRJbnQzMl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8zX0NvbnRhaW5zU3ViTWVzc2FnZVdpdGhSZXBlYXRlZEludDMyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfQ29udGFpbnNTdWJNZXNzYWdlV2l0aFJlcGVhdGVkSW50MzJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN1Yk1zZyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3Rlc3RpbmdfdGV4dGZvcm1hdF9wZXJmb3JtYW5jZV9wcm90bzNfUmVwZWF0ZWRJbnQzMl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl90ZXN0aW5nX3RleHRmb3JtYXRfcGVyZm9ybWFuY2VfcHJvdG8zX1JlcGVhdGVkSW50MzJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdGVzdGluZ190ZXh0Zm9ybWF0X3BlcmZvcm1hbmNlX3Byb3RvM19SZXBlYXRlZEludDMyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWx1ZSIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAAvMIX7RRAQC0UQEANwAAAGNvbS9nb29nbGUvcHJvdG9idWYvd3JhcHBlcnN0ZXN0L1dyYXBwZXJzVGVzdFByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvd3JhcHBlcnNfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgV3JhcHBlcnNUZXN0UHJvdG8gewogIHByaXZhdGUgV3JhcHBlcnNUZXN0UHJvdG8oKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgVG9wTGV2ZWxNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOndyYXBwZXJzX3Rlc3QuVG9wTGV2ZWxNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZDEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZmllbGRfZG91YmxlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZERvdWJsZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGZpZWxkX2RvdWJsZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZ2V0RmllbGREb3VibGUoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZF9kb3VibGUgPSAyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZERvdWJsZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZpZWxkX2Zsb2F0ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkRmxvYXQoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZpZWxkX2Zsb2F0ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmllbGRGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmllbGRfZmxvYXQgPSAzOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyIGdldEZpZWxkRmxvYXRPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBmaWVsZF9pbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBmaWVsZF9pbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQ2NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEZpZWxkSW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGZpZWxkX2ludDY0ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEludDY0T3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGZpZWxkX3VpbnQ2NCA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRVaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBmaWVsZF91aW50NjQgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDY0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGdldEZpZWxkVWludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRfdWludDY0ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIgZ2V0RmllbGRVaW50NjRPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGdldEZpZWxkSW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGZpZWxkX2ludDMyID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEludDMyT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkX3VpbnQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGRVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBmaWVsZF91aW50MzIgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkVWludDMyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGdldEZpZWxkVWludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZmllbGRfdWludDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXIgZ2V0RmllbGRVaW50MzJPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkX2Jvb2wgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJvb2woKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZmllbGRfYm9vbCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRCb29sLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBnZXRGaWVsZEJvb2woKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZmllbGRfYm9vbCA9IDg7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEJvb2xPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZmllbGRfc3RyaW5nID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkX3N0cmluZyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZ2V0RmllbGRTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBmaWVsZF9zdHJpbmcgPSA5OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZFN0cmluZ09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkX2J5dGVzID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBmaWVsZF9ieXRlcyA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRGaWVsZEJ5dGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBmaWVsZF9ieXRlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIGdldEZpZWxkQnl0ZXNPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgd3JhcHBlcnNfdGVzdC5Ub3BMZXZlbE1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUb3BMZXZlbE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6d3JhcHBlcnNfdGVzdC5Ub3BMZXZlbE1lc3NhZ2UpCiAgICAgIFRvcExldmVsTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVG9wTGV2ZWxNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRvcExldmVsTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRvcExldmVsTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUb3BMZXZlbE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfd3JhcHBlcnNfdGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfd3JhcHBlcnNfdGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTEQxX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBmaWVsZDFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQxKCkgewogICAgICByZXR1cm4gZmllbGQxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9ET1VCTEVfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZERvdWJsZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZmllbGRfZG91YmxlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGREb3VibGUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZF9kb3VibGUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXRGaWVsZERvdWJsZSgpIHsKICAgICAgcmV0dXJuIGZpZWxkRG91YmxlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkRG91YmxlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZF9kb3VibGUgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXIgZ2V0RmllbGREb3VibGVPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZERvdWJsZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZERvdWJsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfRkxPQVRfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZpZWxkRmxvYXRfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmllbGRfZmxvYXQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRmxvYXQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZpZWxkX2Zsb2F0ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGdldEZpZWxkRmxvYXQoKSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRGbG9hdF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmaWVsZF9mbG9hdCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyIGdldEZpZWxkRmxvYXRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZEZsb2F0XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRGbG9hdF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGZpZWxkSW50NjRfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZmllbGRfaW50NjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkSW50NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGZpZWxkX2ludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEZpZWxkSW50NjQoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBmaWVsZF9pbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyIGdldEZpZWxkSW50NjRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZEludDY0XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRJbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRVaW50NjRfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGZpZWxkX3VpbnQ2NCA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFVpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRfdWludDY0ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZ2V0RmllbGRVaW50NjQoKSB7CiAgICAgIHJldHVybiBmaWVsZFVpbnQ2NF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRfdWludDY0ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyIGdldEZpZWxkVWludDY0T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGRVaW50NjRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRVaW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZEludDMyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGZpZWxkX2ludDMyID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBnZXRGaWVsZEludDMyKCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMl8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkSW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZmllbGRfaW50MzIgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEludDMyT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGRJbnQzMl8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkSW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VJTlQzMl9GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkVWludDMyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBmaWVsZF91aW50MzIgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFVpbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkX3VpbnQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGdldEZpZWxkVWludDMyKCkgewogICAgICByZXR1cm4gZmllbGRVaW50MzJfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRVaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkX3VpbnQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZFVpbnQzMk9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkVWludDMyXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkVWludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CT09MX0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkQm9vbF87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkX2Jvb2wgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRCb29sKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkX2Jvb2wgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEZpZWxkQm9vbCgpIHsKICAgICAgcmV0dXJuIGZpZWxkQm9vbF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRCb29sXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZmllbGRfYm9vbCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXIgZ2V0RmllbGRCb29sT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZmllbGRCb29sXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEJvb2xfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1NUUklOR19GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkU3RyaW5nXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBmaWVsZF9zdHJpbmcgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkX3N0cmluZyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGdldEZpZWxkU3RyaW5nKCkgewogICAgICByZXR1cm4gZmllbGRTdHJpbmdfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRTdHJpbmdfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkX3N0cmluZyA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZFN0cmluZ09yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkU3RyaW5nXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9CWVRFU19GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkQnl0ZXNfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZmllbGRfYnl0ZXMgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEJ5dGVzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBmaWVsZF9ieXRlcyA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZ2V0RmllbGRCeXRlcygpIHsKICAgICAgcmV0dXJuIGZpZWxkQnl0ZXNfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEJ5dGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkX2J5dGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIGdldEZpZWxkQnl0ZXNPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWVsZEJ5dGVzXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRCeXRlc187CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZmllbGQxXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgZmllbGQxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyLCBnZXRGaWVsZERvdWJsZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldEZpZWxkRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0LCBnZXRGaWVsZEludDY0KCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNSwgZ2V0RmllbGRVaW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg2LCBnZXRGaWVsZEludDMyKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgZ2V0RmllbGRVaW50MzIoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg4LCBnZXRGaWVsZEJvb2woKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCBnZXRGaWVsZFN0cmluZygpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCBnZXRGaWVsZEJ5dGVzKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoZmllbGQxXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBmaWVsZDFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0RmllbGREb3VibGUoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGdldEZpZWxkRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGdldEZpZWxkSW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGdldEZpZWxkVWludDY0KCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBnZXRGaWVsZEludDMyKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCBnZXRGaWVsZFVpbnQzMigpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgZ2V0RmllbGRCb29sKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBnZXRGaWVsZFN0cmluZygpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIGdldEZpZWxkQnl0ZXMoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoZ2V0RmllbGQxKCkKICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZERvdWJsZSgpICE9IG90aGVyLmhhc0ZpZWxkRG91YmxlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkRG91YmxlKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkRG91YmxlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZERvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEZsb2F0KCkgIT0gb3RoZXIuaGFzRmllbGRGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZEZsb2F0KCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkRmxvYXQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRJbnQ2NCgpICE9IG90aGVyLmhhc0ZpZWxkSW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRJbnQ2NCgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZEludDY0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZEludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkVWludDY0KCkgIT0gb3RoZXIuaGFzRmllbGRVaW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRVaW50NjQoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRVaW50NjQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkVWludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkSW50MzIoKSAhPSBvdGhlci5oYXNGaWVsZEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkSW50MzIoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRJbnQzMigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRJbnQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFVpbnQzMigpICE9IG90aGVyLmhhc0ZpZWxkVWludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkVWludDMyKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkVWludDMyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZFVpbnQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEJvb2woKSAhPSBvdGhlci5oYXNGaWVsZEJvb2woKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRCb29sKCkpIHsKICAgICAgICBpZiAoIWdldEZpZWxkQm9vbCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCb29sKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU3RyaW5nKCkgIT0gb3RoZXIuaGFzRmllbGRTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRTdHJpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkQnl0ZXMoKSAhPSBvdGhlci5oYXNGaWVsZEJ5dGVzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkQnl0ZXMoKSkgewogICAgICAgIGlmICghZ2V0RmllbGRCeXRlcygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQxX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGQxKCk7CiAgICAgIGlmIChoYXNGaWVsZERvdWJsZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZERvdWJsZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEZsb2F0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRJbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkSW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZFVpbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZFVpbnQ2NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkSW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZEludDMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRVaW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRVaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZEJvb2woKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQm9vbCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkU3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRCeXRlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSB3cmFwcGVyc190ZXN0LlRvcExldmVsTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOndyYXBwZXJzX3Rlc3QuVG9wTGV2ZWxNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfd3JhcHBlcnNfdGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3dyYXBwZXJzX3Rlc3RfVG9wTGV2ZWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEZpZWxkRG91YmxlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZEZsb2F0RmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZEludDY0RmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGaWVsZFVpbnQ2NEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRJbnQzMkZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRVaW50MzJGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldEZpZWxkQm9vbEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RmllbGRTdHJpbmdGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldEZpZWxkQnl0ZXNGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZpZWxkMV8gPSAwOwogICAgICAgIGZpZWxkRG91YmxlXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkRG91YmxlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGREb3VibGVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZERvdWJsZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZmllbGRGbG9hdF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEZsb2F0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRGbG9hdEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkRmxvYXRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50NjRfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRJbnQ2NEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkSW50NjRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEludDY0QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmaWVsZFVpbnQ2NF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZFVpbnQ2NEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkVWludDY0QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRVaW50NjRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkSW50MzJfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRJbnQzMkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkSW50MzJCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEludDMyQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmaWVsZFVpbnQzMl8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZFVpbnQzMkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkVWludDMyQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRVaW50MzJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkQm9vbF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEJvb2xCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZEJvb2xCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEJvb2xCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkU3RyaW5nXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkU3RyaW5nQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRTdHJpbmdCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZFN0cmluZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZmllbGRCeXRlc18gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEJ5dGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRCeXRlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkQnl0ZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfd3JhcHBlcnNfdGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQxXyA9IGZpZWxkMV87CiAgICAgICAgfQogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkRG91YmxlXyA9IGZpZWxkRG91YmxlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGREb3VibGVfCiAgICAgICAgICAgICAgOiBmaWVsZERvdWJsZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRGbG9hdF8gPSBmaWVsZEZsb2F0QnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRGbG9hdF8KICAgICAgICAgICAgICA6IGZpZWxkRmxvYXRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50NjRfID0gZmllbGRJbnQ2NEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZpZWxkSW50NjRfCiAgICAgICAgICAgICAgOiBmaWVsZEludDY0QnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQ2NF8gPSBmaWVsZFVpbnQ2NEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZpZWxkVWludDY0XwogICAgICAgICAgICAgIDogZmllbGRVaW50NjRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkSW50MzJfID0gZmllbGRJbnQzMkJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZpZWxkSW50MzJfCiAgICAgICAgICAgICAgOiBmaWVsZEludDMyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZFVpbnQzMl8gPSBmaWVsZFVpbnQzMkJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZpZWxkVWludDMyXwogICAgICAgICAgICAgIDogZmllbGRVaW50MzJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkQm9vbF8gPSBmaWVsZEJvb2xCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmaWVsZEJvb2xfCiAgICAgICAgICAgICAgOiBmaWVsZEJvb2xCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkU3RyaW5nXyA9IGZpZWxkU3RyaW5nQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRTdHJpbmdfCiAgICAgICAgICAgICAgOiBmaWVsZFN0cmluZ0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRCeXRlc18gPSBmaWVsZEJ5dGVzQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRCeXRlc18KICAgICAgICAgICAgICA6IGZpZWxkQnl0ZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi53cmFwcGVyc3Rlc3QuV3JhcHBlcnNUZXN0UHJvdG8uVG9wTGV2ZWxNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldEZpZWxkMSgpICE9IDApIHsKICAgICAgICAgIHNldEZpZWxkMShvdGhlci5nZXRGaWVsZDEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZERvdWJsZSgpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkRG91YmxlKG90aGVyLmdldEZpZWxkRG91YmxlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRGbG9hdCgpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkRmxvYXQob3RoZXIuZ2V0RmllbGRGbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkSW50NjQoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZEludDY0KG90aGVyLmdldEZpZWxkSW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZFVpbnQ2NCgpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkVWludDY0KG90aGVyLmdldEZpZWxkVWludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRJbnQzMigpKSB7CiAgICAgICAgICBtZXJnZUZpZWxkSW50MzIob3RoZXIuZ2V0RmllbGRJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkVWludDMyKCkpIHsKICAgICAgICAgIG1lcmdlRmllbGRVaW50MzIob3RoZXIuZ2V0RmllbGRVaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZEJvb2woKSkgewogICAgICAgICAgbWVyZ2VGaWVsZEJvb2wob3RoZXIuZ2V0RmllbGRCb29sKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRTdHJpbmcoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZFN0cmluZyhvdGhlci5nZXRGaWVsZFN0cmluZygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkQnl0ZXMoKSkgewogICAgICAgICAgbWVyZ2VGaWVsZEJ5dGVzKG90aGVyLmdldEZpZWxkQnl0ZXMoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZmllbGQxXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZERvdWJsZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZEZsb2F0RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkSW50NjRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRVaW50NjRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRJbnQzMkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZFVpbnQzMkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZEJvb2xGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRTdHJpbmdGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRCeXRlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGQxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGQxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkMSgpIHsKICAgICAgICByZXR1cm4gZmllbGQxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQxKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkMV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZmllbGREb3VibGVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IGZpZWxkRG91YmxlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGZpZWxkX2RvdWJsZSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkRG91YmxlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZF9kb3VibGUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXRGaWVsZERvdWJsZSgpIHsKICAgICAgICBpZiAoZmllbGREb3VibGVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGREb3VibGVfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGREb3VibGVfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGREb3VibGVCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGZpZWxkX2RvdWJsZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGREb3VibGUoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZERvdWJsZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGREb3VibGVfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkRG91YmxlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZF9kb3VibGUgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkRG91YmxlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZERvdWJsZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkRG91YmxlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZERvdWJsZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZmllbGRfZG91YmxlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkRG91YmxlKGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGREb3VibGVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGREb3VibGVfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGREb3VibGVfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmllbGREb3VibGVCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkRG91YmxlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZERvdWJsZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZERvdWJsZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGZpZWxkX2RvdWJsZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZERvdWJsZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZmllbGREb3VibGVfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGREb3VibGVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZERvdWJsZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkRG91YmxlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBmaWVsZF9kb3VibGUgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIgZ2V0RmllbGREb3VibGVCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RmllbGREb3VibGVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZmllbGRfZG91YmxlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZERvdWJsZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGREb3VibGVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGREb3VibGVCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZERvdWJsZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkRG91YmxlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZmllbGRfZG91YmxlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGREb3VibGVGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkRG91YmxlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGREb3VibGVCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkRG91YmxlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZERvdWJsZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGREb3VibGVCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmllbGRGbG9hdF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gZmllbGRGbG9hdEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZpZWxkX2Zsb2F0ID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEZsb2F0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZpZWxkX2Zsb2F0ID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGdldEZpZWxkRmxvYXQoKSB7CiAgICAgICAgaWYgKGZpZWxkRmxvYXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRGbG9hdF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkRmxvYXRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRGbG9hdEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmaWVsZF9mbG9hdCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRGbG9hdEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRGbG9hdF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRGbG9hdEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmaWVsZF9mbG9hdCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRGbG9hdCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZEZsb2F0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRGbG9hdF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRGbG9hdEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmaWVsZF9mbG9hdCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZEZsb2F0KGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEZsb2F0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApICYmCiAgICAgICAgICAgIGZpZWxkRmxvYXRfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRGbG9hdF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkRmxvYXRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkRmxvYXRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkRmxvYXRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRGbG9hdF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmllbGRfZmxvYXQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRGbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZmllbGRGbG9hdF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEZsb2F0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRGbG9hdEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkRmxvYXRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmllbGRfZmxvYXQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciBnZXRGaWVsZEZsb2F0QnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkRmxvYXRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmaWVsZF9mbG9hdCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEZsb2F0T3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEZsb2F0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkRmxvYXRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEZsb2F0XyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEZsb2F0XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmaWVsZF9mbG9hdCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkRmxvYXRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkRmxvYXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEZsb2F0QnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGaWVsZEZsb2F0KCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZEZsb2F0XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZEZsb2F0QnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGZpZWxkSW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXI+IGZpZWxkSW50NjRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBmaWVsZF9pbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkSW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBmaWVsZF9pbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBnZXRGaWVsZEludDY0KCkgewogICAgICAgIGlmIChmaWVsZEludDY0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEludDY0XzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkSW50NjRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZmllbGRfaW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjQoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkSW50NjRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkSW50NjRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkSW50NjRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZmllbGRfaW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkSW50NjQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRJbnQ2NEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkSW50NjRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkSW50NjRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZmllbGRfaW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRJbnQ2NChjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRJbnQ2NEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZEludDY0XyAhPSBudWxsICYmCiAgICAgICAgICAgIGZpZWxkSW50NjRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRGaWVsZEludDY0QnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZEludDY0XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEludDY0QnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkSW50NjRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGZpZWxkX2ludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkSW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGZpZWxkSW50NjRfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRJbnQ2NEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkSW50NjRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEludDY0QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGZpZWxkX2ludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIgZ2V0RmllbGRJbnQ2NEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGaWVsZEludDY0RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZmllbGRfaW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIgZ2V0RmllbGRJbnQ2NE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRJbnQ2NEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZEludDY0QnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRJbnQ2NF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRJbnQ2NF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZmllbGRfaW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZEludDY0RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEludDY0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRJbnQ2NEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGRJbnQ2NCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRJbnQ2NF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRJbnQ2NEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRVaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IGZpZWxkVWludDY0QnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGZpZWxkX3VpbnQ2NCA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkVWludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkVWludDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBmaWVsZF91aW50NjQgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRGaWVsZFVpbnQ2NCgpIHsKICAgICAgICBpZiAoZmllbGRVaW50NjRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRVaW50NjRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRVaW50NjRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRVaW50NjRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGZpZWxkX3VpbnQ2NCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50NjQoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZFVpbnQ2NEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRVaW50NjRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkVWludDY0QnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBmaWVsZF91aW50NjQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkVWludDY0KAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZFVpbnQ2NEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkVWludDY0XyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRfdWludDY0ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkVWludDY0KGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRVaW50NjRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRVaW50NjRfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRVaW50NjRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmllbGRVaW50NjRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkVWludDY0XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZFVpbnQ2NF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGZpZWxkX3VpbnQ2NCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZFVpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgZmllbGRVaW50NjRfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRVaW50NjRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZFVpbnQ2NEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkVWludDY0QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBmaWVsZF91aW50NjQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIgZ2V0RmllbGRVaW50NjRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RmllbGRVaW50NjRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRfdWludDY0ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZFVpbnQ2NE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRVaW50NjRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRVaW50NjRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZFVpbnQ2NF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkVWludDY0XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZmllbGRfdWludDY0ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRVaW50NjRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkVWludDY0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRVaW50NjRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkVWludDY0KCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZFVpbnQ2NF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRVaW50NjRCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZmllbGRJbnQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlcj4gZmllbGRJbnQzMkJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGZpZWxkX2ludDMyID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZEludDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGZpZWxkX2ludDMyID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGdldEZpZWxkSW50MzIoKSB7CiAgICAgICAgaWYgKGZpZWxkSW50MzJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRJbnQzMl8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkSW50MzJfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRJbnQzMkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMihjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRJbnQzMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZmllbGRJbnQzMl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRJbnQzMkJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRJbnQzMigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWVsZEludDMyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRJbnQzMl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRJbnQzMkJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZEludDMyKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEludDMyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApICYmCiAgICAgICAgICAgIGZpZWxkSW50MzJfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRJbnQzMl8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkSW50MzJCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkSW50MzJfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkSW50MzJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRJbnQzMl8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZmllbGRfaW50MzIgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgZmllbGRJbnQzMl8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEludDMyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRJbnQzMkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpZWxkSW50MzJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZmllbGRfaW50MzIgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciBnZXRGaWVsZEludDMyQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkSW50MzJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEludDMyT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEludDMyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkSW50MzJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEludDMyXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEludDMyXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBmaWVsZF9pbnQzMiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkSW50MzJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkSW50MzJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEludDMyQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGaWVsZEludDMyKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmaWVsZEludDMyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZEludDMyQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBmaWVsZFVpbnQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlcj4gZmllbGRVaW50MzJCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZmllbGRfdWludDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkX3VpbnQzMiA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGdldEZpZWxkVWludDMyKCkgewogICAgICAgIGlmIChmaWVsZFVpbnQzMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZFVpbnQzMl8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFVpbnQzMl87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZmllbGRfdWludDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFVpbnQzMihjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkVWludDMyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaWVsZFVpbnQzMl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRVaW50MzJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkX3VpbnQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRVaW50MzIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkVWludDMyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRVaW50MzJfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkVWludDMyQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBmaWVsZF91aW50MzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGRVaW50MzIoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZFVpbnQzMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSAmJgogICAgICAgICAgICBmaWVsZFVpbnQzMl8gIT0gbnVsbCAmJgogICAgICAgICAgICBmaWVsZFVpbnQzMl8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRGaWVsZFVpbnQzMkJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGRVaW50MzJfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkVWludDMyQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpZWxkVWludDMyXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZmllbGRfdWludDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBmaWVsZFVpbnQzMl8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZFVpbnQzMkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkVWludDMyQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZmllbGRVaW50MzJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGZpZWxkX3VpbnQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBnZXRGaWVsZFVpbnQzMkJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGaWVsZFVpbnQzMkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBmaWVsZF91aW50MzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyIGdldEZpZWxkVWludDMyT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZFVpbnQzMkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkVWludDMyXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRVaW50MzJfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBmaWVsZF91aW50MzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZFVpbnQzMkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRVaW50MzJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZFVpbnQzMkJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGRVaW50MzIoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZpZWxkVWludDMyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZFVpbnQzMkJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkQm9vbF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gZmllbGRCb29sQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBmaWVsZF9ib29sID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRCb29sIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQm9vbCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkX2Jvb2wgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEZpZWxkQm9vbCgpIHsKICAgICAgICBpZiAoZmllbGRCb29sQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkQm9vbF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRCb29sXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkQm9vbEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGZpZWxkX2Jvb2wgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQm9vbChjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEJvb2xCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkQm9vbF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRCb29sQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZmllbGRfYm9vbCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRCb29sKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRCb29sQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRCb29sXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEJvb2xCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBmaWVsZF9ib29sID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkQm9vbChjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEJvb2xCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRCb29sXyAhPSBudWxsICYmCiAgICAgICAgICAgIGZpZWxkQm9vbF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmllbGRCb29sQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZEJvb2xfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkQm9vbEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWVsZEJvb2xfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZmllbGRfYm9vbCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZEJvb2woKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGZpZWxkQm9vbF8gPSBudWxsOwogICAgICAgIGlmIChmaWVsZEJvb2xCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmaWVsZEJvb2xCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEJvb2xCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBmaWVsZF9ib29sID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBnZXRGaWVsZEJvb2xCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RmllbGRCb29sRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBmaWVsZF9ib29sID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXIgZ2V0RmllbGRCb29sT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEJvb2xCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRCb29sQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRCb29sXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkQm9vbF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBmaWVsZF9ib29sID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGRCb29sRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEJvb2xCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEJvb2xCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkQm9vbCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRCb29sXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWVsZEJvb2xCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkU3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPiBmaWVsZFN0cmluZ0J1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBmaWVsZF9zdHJpbmcgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZFN0cmluZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZmllbGRfc3RyaW5nID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZ2V0RmllbGRTdHJpbmcoKSB7CiAgICAgICAgaWYgKGZpZWxkU3RyaW5nQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkU3RyaW5nXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBmaWVsZF9zdHJpbmcgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkU3RyaW5nKGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRTdHJpbmdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZFN0cmluZ0J1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZmllbGRfc3RyaW5nID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZFN0cmluZygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRTdHJpbmdCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZFN0cmluZ18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRTdHJpbmdCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkX3N0cmluZyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZFN0cmluZyhjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkU3RyaW5nQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApICYmCiAgICAgICAgICAgIGZpZWxkU3RyaW5nXyAhPSBudWxsICYmCiAgICAgICAgICAgIGZpZWxkU3RyaW5nXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkU3RyaW5nQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRTdHJpbmdCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRTdHJpbmdfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBmaWVsZF9zdHJpbmcgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGZpZWxkU3RyaW5nXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkU3RyaW5nQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRTdHJpbmdCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZFN0cmluZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZmllbGRfc3RyaW5nID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIGdldEZpZWxkU3RyaW5nQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpZWxkU3RyaW5nRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkX3N0cmluZyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXIgZ2V0RmllbGRTdHJpbmdPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpZWxkU3RyaW5nQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRTdHJpbmdfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZFN0cmluZ187CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGZpZWxkX3N0cmluZyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkU3RyaW5nRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZFN0cmluZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkU3RyaW5nQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGaWVsZFN0cmluZygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRTdHJpbmdfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkU3RyaW5nQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkQnl0ZXNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXI+IGZpZWxkQnl0ZXNCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBmaWVsZF9ieXRlcyA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZmllbGRfYnl0ZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEZpZWxkQnl0ZXMoKSB7CiAgICAgICAgaWYgKGZpZWxkQnl0ZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRCeXRlc18gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkQnl0ZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRCeXRlc0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBmaWVsZF9ieXRlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkQnl0ZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkQnl0ZXNfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkQnl0ZXNCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZmllbGRfYnl0ZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkQnl0ZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmaWVsZEJ5dGVzXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEJ5dGVzQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkX2J5dGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSB2YWx1ZSkgewogICAgICAgIGlmIChmaWVsZEJ5dGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApICYmCiAgICAgICAgICAgIGZpZWxkQnl0ZXNfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRCeXRlc18gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkQnl0ZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkQnl0ZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkQnl0ZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRCeXRlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZmllbGRfYnl0ZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkQnl0ZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGZpZWxkQnl0ZXNfID0gbnVsbDsKICAgICAgICBpZiAoZmllbGRCeXRlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpZWxkQnl0ZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEJ5dGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkX2J5dGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIGdldEZpZWxkQnl0ZXNCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RmllbGRCeXRlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGZpZWxkX2J5dGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlciBnZXRGaWVsZEJ5dGVzT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEJ5dGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkQnl0ZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZEJ5dGVzXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZEJ5dGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBmaWVsZF9ieXRlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZEJ5dGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEJ5dGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRCeXRlc0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmllbGRCeXRlcygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRCeXRlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmllbGRCeXRlc0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOndyYXBwZXJzX3Rlc3QuVG9wTGV2ZWxNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTp3cmFwcGVyc190ZXN0LlRvcExldmVsTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYud3JhcHBlcnN0ZXN0LldyYXBwZXJzVGVzdFByb3RvLlRvcExldmVsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRvcExldmVsTWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUb3BMZXZlbE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUb3BMZXZlbE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUb3BMZXZlbE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VG9wTGV2ZWxNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLndyYXBwZXJzdGVzdC5XcmFwcGVyc1Rlc3RQcm90by5Ub3BMZXZlbE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfd3JhcHBlcnNfdGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfd3JhcHBlcnNfdGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcblwnY29tL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVyc190ZXN0LnByb3QiICsKICAgICAgIm9cMDIyXHJ3cmFwcGVyc190ZXN0XDAzMlwwMzZnb29nbGUvcHJvdG9idWYvd3JhcHBlIiArCiAgICAgICJycy5wcm90b1wiXDM1MVwwMDNcblwwMTdUb3BMZXZlbE1lc3NhZ2VcMDIyXDAxNlxuXDAwNmZpZWxkMVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDA1XDAyMjJcblwwMTRmaWVsZF9kb3VibGVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNC5nb29nbGUucHJvdCIgKwogICAgICAib2J1Zi5Eb3VibGVWYWx1ZVwwMjIwXG5cMDEzZmllbGRfZmxvYXRcMDMwXDAwMyBcMDAxKFwwMTMyXDAzMy4iICsKICAgICAgImdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlXDAyMjBcblwwMTNmaWVsZF9pbnQ2IiArCiAgICAgICI0XDAzMFwwMDQgXDAwMShcMDEzMlwwMzMuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVcMDIyMlxuXDAxNCIgKwogICAgICAiZmllbGRfdWludDY0XDAzMFwwMDUgXDAwMShcMDEzMlwwMzQuZ29vZ2xlLnByb3RvYnVmLlVJbiIgKwogICAgICAidDY0VmFsdWVcMDIyMFxuXDAxM2ZpZWxkX2ludDMyXDAzMFwwMDYgXDAwMShcMDEzMlwwMzMuZ29vZ2xlLnAiICsKICAgICAgInJvdG9idWYuSW50MzJWYWx1ZVwwMjIyXG5cMDE0ZmllbGRfdWludDMyXDAzMFwwMDcgXDAwMShcMDEzIiArCiAgICAgICIyXDAzNC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVcMDIyLlxuXG5maWVsZF8iICsKICAgICAgImJvb2xcMDMwXDAxMCBcMDAxKFwwMTMyXDAzMi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlXDAyMjIiICsKICAgICAgIlxuXDAxNGZpZWxkX3N0cmluZ1wwMzBcdCBcMDAxKFwwMTMyXDAzNC5nb29nbGUucHJvdG9idWYuUyIgKwogICAgICAidHJpbmdWYWx1ZVwwMjIwXG5cMDEzZmllbGRfYnl0ZXNcMDMwXG4gXDAwMShcMDEzMlwwMzMuZ29vZ2xlIiArCiAgICAgICIucHJvdG9idWYuQnl0ZXNWYWx1ZUI1XG4gY29tLmdvb2dsZS5wcm90byIgKwogICAgICAiYnVmLndyYXBwZXJzdGVzdEJcMDIxV3JhcHBlcnNUZXN0UHJvdG9iXDAwNnBybyIgKwogICAgICAidG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldyYXBwZXJzUHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3dyYXBwZXJzX3Rlc3RfVG9wTGV2ZWxNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3dyYXBwZXJzX3Rlc3RfVG9wTGV2ZWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3dyYXBwZXJzX3Rlc3RfVG9wTGV2ZWxNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZDEiLCAiRmllbGREb3VibGUiLCAiRmllbGRGbG9hdCIsICJGaWVsZEludDY0IiwgIkZpZWxkVWludDY0IiwgIkZpZWxkSW50MzIiLCAiRmllbGRVaW50MzIiLCAiRmllbGRCb29sIiwgIkZpZWxkU3RyaW5nIiwgIkZpZWxkQnl0ZXMiLCB9KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuV3JhcHBlcnNQcm90by5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQADUMF9pgQAAKYEAAAjAAAAZGVwcmVjYXRlZF9maWxlL0RlcHJlY2F0ZWRGaWxlLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvZGVwcmVjYXRlZF9maWxlLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBkZXByZWNhdGVkX2ZpbGU7CgpAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGZpbmFsIGNsYXNzIERlcHJlY2F0ZWRGaWxlIHsKICBwcml2YXRlIERlcHJlY2F0ZWRGaWxlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4pY29tL2dvb2dsZS9wcm90b2J1Zi9kZXByZWNhdGVkX2ZpbGUucHIiICsKICAgICAgIm90b1wwMjJcMDE3ZGVwcmVjYXRlZF9maWxlQlwwMDNcMjcwXDAwMVwwMDFiXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEA7NmDq2PKAABjygAALwAAAGR5bmFtaWNtZXNzYWdldGVzdC9EeW5hbWljTWVzc2FnZVRlc3RQcm90by5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBkeW5hbWljbWVzc2FnZXRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8gewogIHByaXZhdGUgRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8oKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgRW1wdHlNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRW1wdHlNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSkKICAgICAgRW1wdHlNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBFbXB0eU1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRW1wdHlNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRW1wdHlNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfRW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9FbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLmNsYXNzLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2Ugb3RoZXIgPSAoZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSkKICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfRW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfRW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UuY2xhc3MsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9FbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHJlc3VsdCA9IG5ldyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6ZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RW1wdHlNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEVtcHR5TWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEVtcHR5TWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEVtcHR5TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxFbXB0eU1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBNZXNzYWdlV2l0aE1hcEZpZWxkc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpkeW5hbWljX21lc3NhZ2VfdGVzdC5NZXNzYWdlV2l0aE1hcEZpZWxkcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nTWVzc2FnZU1hcENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nTWVzc2FnZU1hcCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01lc3NhZ2VNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+CiAgICBnZXRTdHJpbmdNZXNzYWdlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+CiAgICBnZXRTdHJpbmdNZXNzYWdlTWFwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIGdldFN0cmluZ01lc3NhZ2VNYXBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAuZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlJmd0OyBzdHJpbmdfbWVzc2FnZV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBnZXRTdHJpbmdNZXNzYWdlTWFwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIGR5bmFtaWNfbWVzc2FnZV90ZXN0Lk1lc3NhZ2VXaXRoTWFwRmllbGRzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTWVzc2FnZVdpdGhNYXBGaWVsZHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6ZHluYW1pY19tZXNzYWdlX3Rlc3QuTWVzc2FnZVdpdGhNYXBGaWVsZHMpCiAgICAgIE1lc3NhZ2VXaXRoTWFwRmllbGRzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBNZXNzYWdlV2l0aE1hcEZpZWxkcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNZXNzYWdlV2l0aE1hcEZpZWxkcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE1lc3NhZ2VXaXRoTWFwRmllbGRzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE1lc3NhZ2VXaXRoTWFwRmllbGRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdNZXNzYWdlTWFwKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2R5bmFtaWNfbWVzc2FnZV90ZXN0X01lc3NhZ2VXaXRoTWFwRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzLmNsYXNzLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX01FU1NBR0VfTUFQX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdNZXNzYWdlTWFwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2R5bmFtaWNfbWVzc2FnZV90ZXN0X01lc3NhZ2VXaXRoTWFwRmllbGRzX1N0cmluZ01lc3NhZ2VNYXBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4gc3RyaW5nTWVzc2FnZU1hcF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4KICAgIGludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpIHsKICAgICAgaWYgKHN0cmluZ01lc3NhZ2VNYXBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdNZXNzYWdlTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ01lc3NhZ2VNYXBfOwogICAgfQogICAgcHVibGljIGludCBnZXRTdHJpbmdNZXNzYWdlTWFwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ01lc3NhZ2VNYXAoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNZXNzYWdlTWFwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4gZ2V0U3RyaW5nTWVzc2FnZU1hcCgpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ01lc3NhZ2VNYXBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSZndDsgc3RyaW5nX21lc3NhZ2VfbWFwID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+IGdldFN0cmluZ01lc3NhZ2VNYXBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSZndDsgc3RyaW5nX21lc3NhZ2VfbWFwID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIGdldFN0cmluZ01lc3NhZ2VNYXBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBnZXRTdHJpbmdNZXNzYWdlTWFwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdNZXNzYWdlTWFwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpLAogICAgICAgICAgU3RyaW5nTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmdNZXNzYWdlTWFwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4KICAgICAgICBzdHJpbmdNZXNzYWdlTWFwX18gPSBTdHJpbmdNZXNzYWdlTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBzdHJpbmdNZXNzYWdlTWFwX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIG90aGVyID0gKGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcykgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19NRVNTQUdFX01BUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdNZXNzYWdlTWFwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgZHluYW1pY19tZXNzYWdlX3Rlc3QuTWVzc2FnZVdpdGhNYXBGaWVsZHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpkeW5hbWljX21lc3NhZ2VfdGVzdC5NZXNzYWdlV2l0aE1hcEZpZWxkcykKICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdNZXNzYWdlTWFwKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX2R5bmFtaWNfbWVzc2FnZV90ZXN0X01lc3NhZ2VXaXRoTWFwRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcy5jbGFzcywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdNZXNzYWdlTWFwKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgYnVpbGQoKSB7CiAgICAgICAgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgcmVzdWx0ID0gbmV3IGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdNZXNzYWdlTWFwXyA9IGludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpLmJ1aWxkKFN0cmluZ01lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdNZXNzYWdlTWFwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4KICAgICAgICAgICAgICAgIHN0cmluZ01lc3NhZ2VNYXBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFN0cmluZ01lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nTWVzc2FnZU1hcF9fLmdldEtleSgpLCBzdHJpbmdNZXNzYWdlTWFwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nTWVzc2FnZU1hcENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlT3JCdWlsZGVyLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIGJ1aWxkKGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSkgeyByZXR1cm4gKGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgoZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIFN0cmluZ01lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nTWVzc2FnZU1hcENvbnZlcnRlciBzdHJpbmdNZXNzYWdlTWFwQ29udmVydGVyID0gbmV3IFN0cmluZ01lc3NhZ2VNYXBDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlT3JCdWlsZGVyLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLkJ1aWxkZXI+IHN0cmluZ01lc3NhZ2VNYXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2VPckJ1aWxkZXIsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpIHsKICAgICAgICBpZiAoc3RyaW5nTWVzc2FnZU1hcF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHN0cmluZ01lc3NhZ2VNYXBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nTWVzc2FnZU1hcF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlT3JCdWlsZGVyLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdNZXNzYWdlTWFwKCkgewogICAgICAgIGlmIChzdHJpbmdNZXNzYWdlTWFwXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdNZXNzYWdlTWFwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHN0cmluZ01lc3NhZ2VNYXBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ01lc3NhZ2VNYXBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nTWVzc2FnZU1hcENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ01lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAuZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlJmd0OyBzdHJpbmdfbWVzc2FnZV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdNZXNzYWdlTWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdNZXNzYWdlTWFwKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01lc3NhZ2VNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+IGdldFN0cmluZ01lc3NhZ2VNYXAoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ01lc3NhZ2VNYXBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSZndDsgc3RyaW5nX21lc3NhZ2VfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+IGdldFN0cmluZ01lc3NhZ2VNYXBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nTWVzc2FnZU1hcCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAuZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlJmd0OyBzdHJpbmdfbWVzc2FnZV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UgZ2V0U3RyaW5nTWVzc2FnZU1hcE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVN0cmluZ01lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gc3RyaW5nTWVzc2FnZU1hcENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAuZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlJmd0OyBzdHJpbmdfbWVzc2FnZV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2UgZ2V0U3RyaW5nTWVzc2FnZU1hcE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nTWVzc2FnZU1hcENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nTWVzc2FnZU1hcCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3RyaW5nTWVzc2FnZU1hcCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmdNZXNzYWdlTWFwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLmR5bmFtaWNfbWVzc2FnZV90ZXN0LkVtcHR5TWVzc2FnZSZndDsgc3RyaW5nX21lc3NhZ2VfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmdNZXNzYWdlTWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ01lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5keW5hbWljX21lc3NhZ2VfdGVzdC5FbXB0eU1lc3NhZ2UmZ3Q7IHN0cmluZ19tZXNzYWdlX21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nTWVzc2FnZU1hcCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5FbXB0eU1lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAuZHluYW1pY19tZXNzYWdlX3Rlc3QuRW1wdHlNZXNzYWdlJmd0OyBzdHJpbmdfbWVzc2FnZV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLkJ1aWxkZXIgcHV0U3RyaW5nTWVzc2FnZU1hcEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uRW1wdHlNZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgoZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLkVtcHR5TWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpkeW5hbWljX21lc3NhZ2VfdGVzdC5NZXNzYWdlV2l0aE1hcEZpZWxkcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6ZHluYW1pY19tZXNzYWdlX3Rlc3QuTWVzc2FnZVdpdGhNYXBGaWVsZHMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgZHluYW1pY21lc3NhZ2V0ZXN0LkR5bmFtaWNNZXNzYWdlVGVzdFByb3RvLk1lc3NhZ2VXaXRoTWFwRmllbGRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBkeW5hbWljbWVzc2FnZXRlc3QuRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uTWVzc2FnZVdpdGhNYXBGaWVsZHMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlV2l0aE1hcEZpZWxkcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlV2l0aE1hcEZpZWxkcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE1lc3NhZ2VXaXRoTWFwRmllbGRzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVdpdGhNYXBGaWVsZHM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVdpdGhNYXBGaWVsZHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGR5bmFtaWNtZXNzYWdldGVzdC5EeW5hbWljTWVzc2FnZVRlc3RQcm90by5NZXNzYWdlV2l0aE1hcEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9FbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfRW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfTWVzc2FnZVdpdGhNYXBGaWVsZHNfU3RyaW5nTWVzc2FnZU1hcEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX2R5bmFtaWNfbWVzc2FnZV90ZXN0X01lc3NhZ2VXaXRoTWFwRmllbGRzX1N0cmluZ01lc3NhZ2VNYXBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuLmNvbS9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlX3RlIiArCiAgICAgICJzdC5wcm90b1wwMjJcMDI0ZHluYW1pY19tZXNzYWdlX3Rlc3RcIlwwMTZcblwwMTRFbXB0eU0iICsKICAgICAgImVzc2FnZVwiXDMyMVwwMDFcblwwMjRNZXNzYWdlV2l0aE1hcEZpZWxkc1wwMjJcXFxuXDAyMnN0cmluIiArCiAgICAgICJnX21lc3NhZ2VfbWFwXDAzMFwwMDEgXDAwMyhcMDEzMkAuZHluYW1pY19tZXNzYWdlX3RlIiArCiAgICAgICJzdC5NZXNzYWdlV2l0aE1hcEZpZWxkcy5TdHJpbmdNZXNzYWdlTWFwIiArCiAgICAgICJFbnRyeVwwMzJbXG5cMDI1U3RyaW5nTWVzc2FnZU1hcEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXHRcMDIyMVxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwiLmR5bmFtaWNfbWVzc2FnZV90ZXMiICsKICAgICAgInQuRW1wdHlNZXNzYWdlOlwwMDI4XDAwMUItXG5cMDIyZHluYW1pY21lc3NhZ2V0ZXN0IiArCiAgICAgICJCXDAyN0R5bmFtaWNNZXNzYWdlVGVzdFByb3RvIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfRW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX2R5bmFtaWNfbWVzc2FnZV90ZXN0X0VtcHR5TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9FbXB0eU1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfTWVzc2FnZVdpdGhNYXBGaWVsZHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfTWVzc2FnZVdpdGhNYXBGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfZHluYW1pY19tZXNzYWdlX3Rlc3RfTWVzc2FnZVdpdGhNYXBGaWVsZHNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN0cmluZ01lc3NhZ2VNYXAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19TdHJpbmdNZXNzYWdlTWFwRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX2R5bmFtaWNfbWVzc2FnZV90ZXN0X01lc3NhZ2VXaXRoTWFwRmllbGRzX1N0cmluZ01lc3NhZ2VNYXBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19keW5hbWljX21lc3NhZ2VfdGVzdF9NZXNzYWdlV2l0aE1hcEZpZWxkc19TdHJpbmdNZXNzYWdlTWFwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEA0mSmKCKjCQAiowkAKAAAAG1hcF9saXRlX3Rlc3QvTWFwRm9yUHJvdG8yVGVzdFByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBtYXBfbGl0ZV90ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIE1hcEZvclByb3RvMlRlc3RQcm90byB7CiAgcHJpdmF0ZSBNYXBGb3JQcm90bzJUZXN0UHJvdG8oKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1hcE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBnZXRJbnQzMlRvRW51bUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4KICAgIGdldFJlcXVpcmVkTWVzc2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPgogICAgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwKQogICAgICBUZXN0TWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWFwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNYXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZX0KICAgICAqLwogICAgcHVibGljIGVudW0gRW51bVZhbHVlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBGT08oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBUigxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFaKDIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+UVVYID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBRVVgoMyksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9WQUxVRSA9IDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5RVVggPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFFVWF9WQUxVRSA9IDM7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBFbnVtVmFsdWUgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIEVudW1WYWx1ZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gRk9POwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gQkFSOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFaOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gUVVYOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bVZhbHVlPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgRW51bVZhbHVlPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bVZhbHVlPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgRW51bVZhbHVlIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBFbnVtVmFsdWUuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVudW1WYWx1ZVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBFbnVtVmFsdWUgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUpCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBNZXNzYWdlVmFsdWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzVmFsdWUoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgaW50IGdldFZhbHVlKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNZXNzYWdlVmFsdWUgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkKICAgICAgICBNZXNzYWdlVmFsdWVPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBNZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBNZXNzYWdlVmFsdWUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBNZXNzYWdlVmFsdWUoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTWVzc2FnZVZhbHVlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBvdGhlciA9IChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgb2JqOwoKICAgICAgICBpZiAoaGFzVmFsdWUoKSAhPSBvdGhlci5oYXNWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICAgIGlmIChnZXRWYWx1ZSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0VmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZBTFVFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFZhbHVlKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlKQogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBidWlsZCgpIHsKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSByZXN1bHQgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQudmFsdWVfID0gdmFsdWVfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzVmFsdWUoKSkgewogICAgICAgICAgICBzZXRWYWx1ZShvdGhlci5nZXRWYWx1ZSgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICB2YWx1ZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCB2YWx1ZV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VmFsdWUoaW50IHZhbHVlKSB7CgogICAgICAgICAgdmFsdWVfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VWYWx1ZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE1lc3NhZ2VWYWx1ZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBNZXNzYWdlVmFsdWUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlVmFsdWU+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlVmFsdWU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1ZhbHVlKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIGludCBnZXRWYWx1ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMpCiAgICAgICAgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcygpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmICghaGFzVmFsdWUoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIG90aGVyID0gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykgb2JqOwoKICAgICAgICBpZiAoaGFzVmFsdWUoKSAhPSBvdGhlci5oYXNWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICAgIGlmIChnZXRWYWx1ZSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0VmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZBTFVFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFZhbHVlKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKQogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgYnVpbGQoKSB7CiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcmVzdWx0ID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQudmFsdWVfID0gdmFsdWVfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcylvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1ZhbHVlKCkpIHsKICAgICAgICAgICAgc2V0VmFsdWUob3RoZXIuZ2V0VmFsdWUoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgaWYgKCFoYXNWYWx1ZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIHZhbHVlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgICB2YWx1ZV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19TVFJJTkdfRklFTERfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0VudW1GaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+IGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkSW50MzJUb0VudW1GaWVsZE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX01FU1NBR0VfTUFQX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUmVxdWlyZWRNZXNzYWdlTWFwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfUmVxdWlyZWRNZXNzYWdlTWFwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IHJlcXVpcmVkTWVzc2FnZU1hcF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4KICAgIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICBpZiAocmVxdWlyZWRNZXNzYWdlTWFwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgUmVxdWlyZWRNZXNzYWdlTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZU1hcF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFJlcXVpcmVkTWVzc2FnZU1hcENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1JlcXVpcmVkTWVzc2FnZU1hcCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBnZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKSB7CiAgICAgIHJldHVybiBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGdldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGdldFJlcXVpcmVkTWVzc2FnZU1hcE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGZvciAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGl0ZW0gOiBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKS52YWx1ZXMoKSkgewogICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLAogICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSwKICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSwKICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLAogICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLAogICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLAogICAgICAgICAgUmVxdWlyZWRNZXNzYWdlTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaW50MzJUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfXyA9IEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgaW50MzJUb1N0cmluZ0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXyA9IEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBpbnQzMlRvQnl0ZXNGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9FbnVtRmllbGRfXyA9IEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGludDMyVG9FbnVtRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4KICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18gPSBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBpbnQzMlRvTWVzc2FnZUZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18gPSBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHN0cmluZ1RvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4KICAgICAgICByZXF1aXJlZE1lc3NhZ2VNYXBfXyA9IFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEsIHJlcXVpcmVkTWVzc2FnZU1hcF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIG90aGVyID0gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9NRVNTQUdFX01BUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcCkKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgYnVpbGQoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcmVzdWx0ID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9JbnQzMkZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9CeXRlc0ZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0VudW1GaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9NZXNzYWdlRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuYnVpbGQoSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcXVpcmVkTWVzc2FnZU1hcF8gPSBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmJ1aWxkKFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXApIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgZm9yIChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgaXRlbSA6IGdldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvU3RyaW5nRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0J5dGVzRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18gPSBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5mb3JOdW1iZXIoaW50MzJUb0VudW1GaWVsZF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoNCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9FbnVtRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18uZ2V0S2V5KCksIHN0cmluZ1RvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPgogICAgICAgICAgICAgICAgcmVxdWlyZWRNZXNzYWdlTWFwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBSZXF1aXJlZE1lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VNYXBfXy5nZXRLZXkoKSwgcmVxdWlyZWRNZXNzYWdlTWFwX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGludDMyVG9JbnQzMkZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb1N0cmluZ0ZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkXyA9IGludDMyVG9TdHJpbmdGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0J5dGVzRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9CeXRlc0ZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfID0gaW50MzJUb0J5dGVzRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0VudW1GaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvRW51bUZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0VudW1GaWVsZF8gPSBpbnQzMlRvRW51bUZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgICAgZ2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgICBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBnZXRJbnQzMlRvRW51bUZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBidWlsZChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgeyByZXR1cm4gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIgaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlciA9IG5ldyBJbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlcj4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihpbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlciBwdXRJbnQzMlRvTWVzc2FnZUZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSB7CiAgICAgICAgICBlbnRyeSA9ICgobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ1RvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBzdHJpbmdUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgYnVpbGQobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykgeyByZXR1cm4gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBSZXF1aXJlZE1lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUmVxdWlyZWRNZXNzYWdlTWFwQ29udmVydGVyIHJlcXVpcmVkTWVzc2FnZU1hcENvbnZlcnRlciA9IG5ldyBSZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5CdWlsZGVyPiByZXF1aXJlZE1lc3NhZ2VNYXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpIHsKICAgICAgICBpZiAocmVxdWlyZWRNZXNzYWdlTWFwXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4ocmVxdWlyZWRNZXNzYWdlTWFwQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZU1hcF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VNYXBfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZU1hcF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihyZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZU1hcF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGdldFJlcXVpcmVkTWVzc2FnZU1hcCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVxdWlyZWRNZXNzYWdlTWFwTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGdldFJlcXVpcmVkTWVzc2FnZU1hcE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IHJlcXVpcmVkTWVzc2FnZU1hcENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlTWFwQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZE1lc3NhZ2VNYXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVxdWlyZWRNZXNzYWdlTWFwKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+CiAgICAgICAgICBnZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFJlcXVpcmVkTWVzc2FnZU1hcCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuQnVpbGRlciBwdXRSZXF1aXJlZE1lc3NhZ2VNYXBCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMpIHsKICAgICAgICAgIGVudHJ5ID0gKChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFVua25vd25FbnVtVmFsdWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RVbmtub3duRW51bVZhbHVlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFVua25vd25FbnVtVmFsdWV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0VW5rbm93bkVudW1WYWx1ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFVua25vd25FbnVtVmFsdWUpCiAgICAgIFRlc3RVbmtub3duRW51bVZhbHVlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VW5rbm93bkVudW1WYWx1ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VW5rbm93bkVudW1WYWx1ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RVbmtub3duRW51bVZhbHVlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RVbmtub3duRW51bVZhbHVlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIG90aGVyID0gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0VW5rbm93bkVudW1WYWx1ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0VW5rbm93bkVudW1WYWx1ZSkKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZS5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBidWlsZCgpIHsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSByZXN1bHQgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gaW50MzJUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0VW5rbm93bkVudW1WYWx1ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RVbmtub3duRW51bVZhbHVlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVua25vd25FbnVtVmFsdWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVua25vd25FbnVtVmFsdWU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbmtub3duRW51bVZhbHVlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbmtub3duRW51bVZhbHVlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXApCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICovCiAgICBpbnQgZ2V0VmFsdWUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZWN1cnNpdmVNYXBGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNSZWN1cnNpdmVNYXBGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPgogICAgZ2V0UmVjdXJzaXZlTWFwRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4KICAgIGdldFJlY3Vyc2l2ZU1hcEZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgdGhhdCB0aGUgbWFwcyBpbml0aWFsaXphdGlvbiBjb2RlIHdvcmtzIGNvcnJlY3RseSB3aGVuIHRoZSBtYXAgZmllbGQKICAgKiByZWZlcmVuY2VzIHRoZSBjb250YWluaW5nIG1lc3NhZ2UuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZWN1cnNpdmVNYXAgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXApCiAgICAgIFRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZWN1cnNpdmVNYXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlY3Vyc2l2ZU1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZWN1cnNpdmVNYXAoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlY3Vyc2l2ZU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IHZhbHVlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICByZXR1cm4gdmFsdWVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQ1VSU0lWRV9NQVBfRklFTERfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFJlY3Vyc2l2ZU1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9SZWN1cnNpdmVNYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+IHJlY3Vyc2l2ZU1hcEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4KICAgIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKSB7CiAgICAgIGlmIChyZWN1cnNpdmVNYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFJlY3Vyc2l2ZU1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlY3Vyc2l2ZU1hcEZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0UmVjdXJzaXZlTWFwRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUmVjdXJzaXZlTWFwRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRSZWN1cnNpdmVNYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBnZXRSZWN1cnNpdmVNYXBGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldFJlY3Vyc2l2ZU1hcEZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBnZXRSZWN1cnNpdmVNYXBGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBnZXRSZWN1cnNpdmVNYXBGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHZhbHVlXyk7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLAogICAgICAgICAgUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMik7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHZhbHVlXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPgogICAgICAgIHJlY3Vyc2l2ZU1hcEZpZWxkX18gPSBSZWN1cnNpdmVNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgcmVjdXJzaXZlTWFwRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBvdGhlciA9IChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKSBvYmo7CgogICAgICBpZiAoaGFzVmFsdWUoKSAhPSBvdGhlci5oYXNWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgaWYgKGdldFZhbHVlKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0VmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZBTFVFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRWYWx1ZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFQ1VSU0lWRV9NQVBfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgdGhhdCB0aGUgbWFwcyBpbml0aWFsaXphdGlvbiBjb2RlIHdvcmtzIGNvcnJlY3RseSB3aGVuIHRoZSBtYXAgZmllbGQKICAgICAqIHJlZmVyZW5jZXMgdGhlIGNvbnRhaW5pbmcgbWVzc2FnZS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXApCiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIGJ1aWxkKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudmFsdWVfID0gdmFsdWVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlY3Vyc2l2ZU1hcEZpZWxkXyA9IGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5idWlsZChSZWN1cnNpdmVNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICBzZXRWYWx1ZShvdGhlci5nZXRWYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgdmFsdWVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+CiAgICAgICAgICAgICAgICByZWN1cnNpdmVNYXBGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZU1hcEZpZWxkX18uZ2V0S2V5KCksIHJlY3Vyc2l2ZU1hcEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgdmFsdWVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBidWlsZChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXApIHsgcmV0dXJuIChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIgcmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIgPSBuZXcgUmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyPiByZWN1cnNpdmVNYXBGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZU1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4ocmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVjdXJzaXZlTWFwRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkgewogICAgICAgIGlmIChyZWN1cnNpdmVNYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmVjdXJzaXZlTWFwRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4ocmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHJlY3Vyc2l2ZU1hcEZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFJlY3Vyc2l2ZU1hcEZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1JlY3Vyc2l2ZU1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRSZWN1cnNpdmVNYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+IGdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRSZWN1cnNpdmVNYXBGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gcmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVjdXJzaXZlTWFwRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlY3Vyc2l2ZU1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZWN1cnNpdmVNYXBGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPgogICAgICAgICAgZ2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRSZWN1cnNpdmVNYXBGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFJlY3Vyc2l2ZU1hcEZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyIHB1dFJlY3Vyc2l2ZU1hcEZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKSB7CiAgICAgICAgICBlbnRyeSA9ICgobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlc3RSZWN1cnNpdmVNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlTWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZWN1cnNpdmVNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVjdXJzaXZlTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlY3Vyc2l2ZU1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlTWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQml6YXJyb1Rlc3RNYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9FbnVtRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9NZXNzYWdlRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBhIGRlY295IG9mIFRlc3RNYXAgZm9yIHRlc3RpbmcgcGFyc2luZyBlcnJvcnMKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5CaXphcnJvVGVzdE1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJpemFycm9UZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5CaXphcnJvVGVzdE1hcCkKICAgICAgQml6YXJyb1Rlc3RNYXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEJpemFycm9UZXN0TWFwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEJpemFycm9UZXN0TWFwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQml6YXJyb1Rlc3RNYXAoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQml6YXJyb1Rlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX0JZVEVTX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9FbnVtRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9FbnVtRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9FbnVtRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9NZXNzYWdlRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9NZXNzYWdlRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLAogICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSwKICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLAogICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSwKICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSwKICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpbnQzMlRvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBpbnQzMlRvU3RyaW5nRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9CeXRlc0ZpZWxkX18gPSBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgaW50MzJUb0J5dGVzRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18gPSBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBpbnQzMlRvRW51bUZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18gPSBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHN0cmluZ1RvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgb3RoZXIgPSAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19TVFJJTkdfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19CWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19FTlVNX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGEgZGVjb3kgb2YgVGVzdE1hcCBmb3IgdGVzdGluZyBwYXJzaW5nIGVycm9ycwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBidWlsZCgpIHsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCByZXN1bHQgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvU3RyaW5nRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvU3RyaW5nRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0J5dGVzRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvRW51bUZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9NZXNzYWdlRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdUb0ludDMyRmllbGRfID0gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvU3RyaW5nRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9CeXRlc0ZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvRW51bUZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvTWVzc2FnZUZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18uZ2V0S2V5KCksIHN0cmluZ1RvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0ludDMyRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF8gPSBpbnQzMlRvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb1N0cmluZ0ZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkXyA9IGludDMyVG9TdHJpbmdGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9CeXRlc0ZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfID0gaW50MzJUb0J5dGVzRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9FbnVtRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9FbnVtRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0VudW1GaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfID0gaW50MzJUb0VudW1GaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvTWVzc2FnZUZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF8gPSBpbnQzMlRvTWVzc2FnZUZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoc3RyaW5nVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ1RvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBzdHJpbmdUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFN0cmluZ1RvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuQml6YXJyb1Rlc3RNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCaXphcnJvVGVzdE1hcD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxCaXphcnJvVGVzdE1hcD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJpemFycm9UZXN0TWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qml6YXJyb1Rlc3RNYXA+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qml6YXJyb1Rlc3RNYXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUmVzZXJ2ZWRBc01hcEZpZWxkT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJZkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SWZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDb25zdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q29uc3RNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q29uc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q29uc3RNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENvbnN0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFByaXZhdGVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQcml2YXRlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENsYXNzX01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Vm9pZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFBhY2thZ2VNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFBhY2thZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEVudW1NYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE51bGxDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXROdWxsKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFVzZWQgdG8gdGVzdCB0aGF0IGphdmEgcmVzZXJ2ZWQgd29yZHMgY2FuIGJlIHVzZWQgYXMgcHJvdG9idWYgZmllbGQgbmFtZXMKICAgKiBOb3QgYWxsIHJlc2VydmVkIHdvcmRzIGFyZSB0ZXN0ZWQgKHRvIGF2b2lkIGJsb2F0KSBidXQgaW5zdGVhZCBhbiBhcmJpdHJhcnkKICAgKiBzdWJzZXQgb2YgdGhlbSBjaG9zZW4gdG8gY292ZXIgdmFyaW91cyBrZXl3b3JkIGNhdGVnb3JpZXMgbGlrZQogICAqIHR5cGUsIG1vZGlmaWVyLCBkZWNsYXJhdGlvbiwgZXRjLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlc2VydmVkQXNNYXBGaWVsZCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkKQogICAgICBSZXNlcnZlZEFzTWFwRmllbGRPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFJlc2VydmVkQXNNYXBGaWVsZC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBSZXNlcnZlZEFzTWFwRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBSZXNlcnZlZEFzTWFwRmllbGQoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUmVzZXJ2ZWRBc01hcEZpZWxkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKTsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpOwogICAgICAgIGNhc2UgOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSWZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaWZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaWZfOwogICAgfQogICAgcHVibGljIGludCBnZXRJZkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmKCkgewogICAgICByZXR1cm4gZ2V0SWZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SWZNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJZk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJZk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09OU1RfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgIGlmIChjb25zdF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbnN0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDb25zdCgpIHsKICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSVZBVEVfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwcml2YXRlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0UHJpdmF0ZSgpIHsKICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgfQogICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFByaXZhdGUoKSB7CiAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY2xhc3NfXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNsYXNzX187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDbGFzc18oKSB7CiAgICAgIHJldHVybiBnZXRDbGFzc19NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludCgpIHsKICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludCgpIHsKICAgICAgcmV0dXJuIGdldEludE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWT0lEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdm9pZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFZvaWQoKSB7CiAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRWb2lkKCkgewogICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFZvaWRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0FHRV9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHBhY2thZ2VfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcGFja2FnZV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2FnZSgpIHsKICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQYWNrYWdlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRW51bURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9FbnVtRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudW1fOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRFbnVtKCkgewogICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZW51bV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RW51bSgpIHsKICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVMTF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE51bGxEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBudWxsXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TnVsbCgpIHsKICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG51bGxfOwogICAgfQogICAgcHVibGljIGludCBnZXROdWxsQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXROdWxsKCkgewogICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXROdWxsTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLAogICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLAogICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCksCiAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCksCiAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKSwKICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKSwKICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKSwKICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSwKICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCksCiAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLAogICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaWZfXyA9IElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpZl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgY29uc3RfXyA9IENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBjb25zdF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBwcml2YXRlX18gPSBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBwcml2YXRlX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgY2xhc3NfX18gPSBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGNsYXNzX19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludF9fID0gSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBpbnRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdm9pZF9fID0gVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgdm9pZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHN0cmluZ19fID0gU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCBzdHJpbmdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgcGFja2FnZV9fID0gUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgcGFja2FnZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBlbnVtX18gPSBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBlbnVtX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIG51bGxfXyA9IE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCBudWxsX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIG90aGVyID0gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldElmKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Q29uc3QoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENvbnN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRQcml2YXRlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRQcml2YXRlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRDbGFzc18oKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0SW50KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFZvaWQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFZvaWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRQYWNrYWdlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRQYWNrYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRFbnVtKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRFbnVtKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXROdWxsKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSUZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SWYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENPTlNUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldENvbnN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBSSVZBVEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0UHJpdmF0ZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENMQVNTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldENsYXNzXygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVk9JRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRWb2lkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFBhY2thZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRFbnVtKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5VTExfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TnVsbCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBVc2VkIHRvIHRlc3QgdGhhdCBqYXZhIHJlc2VydmVkIHdvcmRzIGNhbiBiZSB1c2VkIGFzIHByb3RvYnVmIGZpZWxkIG5hbWVzCiAgICAgKiBOb3QgYWxsIHJlc2VydmVkIHdvcmRzIGFyZSB0ZXN0ZWQgKHRvIGF2b2lkIGJsb2F0KSBidXQgaW5zdGVhZCBhbiBhcmJpdHJhcnkKICAgICAqIHN1YnNldCBvZiB0aGVtIGNob3NlbiB0byBjb3ZlciB2YXJpb3VzIGtleXdvcmQgY2F0ZWdvcmllcyBsaWtlCiAgICAgKiB0eXBlLCBtb2RpZmllciwgZGVjbGFyYXRpb24sIGV0Yy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkKQogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJZigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVWb2lkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUVudW0oKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVOdWxsKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGJ1aWxkKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaWZfID0gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgcmVzdWx0LmlmXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY29uc3RfID0gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgcmVzdWx0LmNvbnN0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8gPSBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIHJlc3VsdC5wcml2YXRlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXyA9IGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50XyA9IGludGVybmFsR2V0SW50KCk7CiAgICAgICAgICByZXN1bHQuaW50Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudm9pZF8gPSBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICAgIHJlc3VsdC52b2lkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXyA9IGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8gPSBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrYWdlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZW51bV8gPSBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIHJlc3VsdC5lbnVtXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubnVsbF8gPSBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIHJlc3VsdC5udWxsXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SWYoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENvbnN0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFByaXZhdGUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDbGFzc18oKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Vm9pZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRQYWNrYWdlKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVudW0oKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TnVsbCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGlmX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaWZfXy5nZXRLZXkoKSwgaWZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjb25zdF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGNvbnN0X18uZ2V0S2V5KCksIGNvbnN0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcHJpdmF0ZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBwcml2YXRlX18uZ2V0S2V5KCksIHByaXZhdGVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjbGFzc19fXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGNsYXNzX19fLmdldEtleSgpLCBjbGFzc19fXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludF9fLmdldEtleSgpLCBpbnRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB2b2lkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHZvaWRfXy5nZXRLZXkoKSwgdm9pZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHN0cmluZ19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nX18uZ2V0S2V5KCksIHN0cmluZ19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHBhY2thZ2VfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgcGFja2FnZV9fLmdldEtleSgpLCBwYWNrYWdlX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZW51bV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBlbnVtX18uZ2V0S2V5KCksIGVudW1fXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBudWxsX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG51bGxfXy5nZXRLZXkoKSwgbnVsbF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpZl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpZl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKSB7CiAgICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgICBpZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaWZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpZl8gPSBpZl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldElmQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmKCkgewogICAgICAgIHJldHVybiBnZXRJZk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJZk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcklmKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSWYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJZigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJZigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBjb25zdF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb25zdF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKSB7CiAgICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgICBjb25zdF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghY29uc3RfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjb25zdF8gPSBjb25zdF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENvbnN0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0KCkgewogICAgICAgIHJldHVybiBnZXRDb25zdE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDb25zdE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVDb25zdCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxDb25zdCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwcml2YXRlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkgewogICAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKSB7CiAgICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICAgIHByaXZhdGVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcHJpdmF0ZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHByaXZhdGVfID0gcHJpdmF0ZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UHJpdmF0ZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UHJpdmF0ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFByaXZhdGVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclByaXZhdGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlUHJpdmF0ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsUHJpdmF0ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgICBjbGFzc19fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjbGFzc19fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjbGFzc19fID0gY2xhc3NfXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY2xhc3NfXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfKCkgewogICAgICAgIHJldHVybiBnZXRDbGFzc19NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDbGFzc19PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDbGFzc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Q2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxDbGFzc18oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50KCkgewogICAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpIHsKICAgICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgICBpbnRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnRfID0gaW50Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2b2lkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkgewogICAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZvaWRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKSB7CiAgICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICAgIHZvaWRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdm9pZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHZvaWRfID0gdm9pZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHZvaWRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Vm9pZCgpIHsKICAgICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFZvaWRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZvaWQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlVm9pZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Vm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVm9pZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdfID0gc3RyaW5nXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gc3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpIHsKICAgICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkgewogICAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICBwYWNrYWdlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXBhY2thZ2VfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBwYWNrYWdlXyA9IHBhY2thZ2VfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFBhY2thZ2UoKSB7CiAgICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQYWNrYWdlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVBhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFBhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFBhY2thZ2UoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnVtXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkgewogICAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVudW1fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKSB7CiAgICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICAgIGVudW1fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZW51bV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGVudW1fID0gZW51bV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGVudW1fOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtKCkgewogICAgICAgIHJldHVybiBnZXRFbnVtTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEVudW1PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxFbnVtKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpIHsKICAgICAgICBpZiAobnVsbF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkgewogICAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgICBudWxsXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW51bGxfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBudWxsXyA9IG51bGxfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBudWxsXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bGxDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldE51bGwoKSB7CiAgICAgICAgcmV0dXJuIGdldE51bGxNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXROdWxsTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOdWxsKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU51bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE51bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE51bGwoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBSZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJZkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSWYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SWYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SWZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENvbnN0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENvbnN0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQcml2YXRlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UHJpdmF0ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzX01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEludE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Vm9pZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFZvaWRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRTdHJpbmdNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQYWNrYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEVudW0oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRFbnVtTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE51bGxDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldE51bGxNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpCiAgICAgIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgY2FzZSA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpOwogICAgICAgIGNhc2UgMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gU2FtcGxlRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkEgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEEoMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBCKDEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+QSA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCX1ZBTFVFID0gMTsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFNhbXBsZUVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIFNhbXBsZUVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEE7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBCOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8U2FtcGxlRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIFNhbXBsZUVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxTYW1wbGVFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgU2FtcGxlRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU2FtcGxlRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2FtcGxlRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBTYW1wbGVFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgU2FtcGxlRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0pCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElmRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgIGlmIChpZl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGlmXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGlmVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgaWZWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldElmQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldElmKCkgewogICAgICByZXR1cm4gZ2V0SWZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldElmTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBpZlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTlNUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDb25zdERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBjb25zdF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldENvbnN0KCkgewogICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBjb25zdF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBjb25zdFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGNvbnN0VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRDb25zdENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ29uc3QoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q29uc3RNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdCgpIHsKICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENvbnN0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENvbnN0T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBjb25zdFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUklWQVRFX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcHJpdmF0ZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFByaXZhdGUoKSB7CiAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBwcml2YXRlXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHByaXZhdGVWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHByaXZhdGVWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQcml2YXRlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFByaXZhdGUoKSB7CiAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFByaXZhdGVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHByaXZhdGVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByaXZhdGVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldENsYXNzXygpIHsKICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBjbGFzc19fOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gY2xhc3NfVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGNsYXNzX1ZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDbGFzc18oKSB7CiAgICAgIHJldHVybiBnZXRDbGFzc19NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzX01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gY2xhc3NfVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQoKSB7CiAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGludFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBpbnRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEludCgpIHsKICAgICAgcmV0dXJuIGdldEludE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEludE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludE1hcCgKICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gaW50VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVk9JRF9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVm9pZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZvaWRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRWb2lkKCkgewogICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdm9pZF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2b2lkVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB2b2lkVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkKCkgewogICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFN0cmluZygpIHsKICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gc3RyaW5nVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHN0cmluZ1ZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRTdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gc3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tBR0VfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrYWdlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0UGFja2FnZSgpIHsKICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gcGFja2FnZVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRQYWNrYWdlTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgcGFja2FnZVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZSgpIHsKICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFBhY2thZ2VNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gcGFja2FnZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gcGFja2FnZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEVudW1EZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnVtXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RW51bSgpIHsKICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGVudW1fOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gZW51bVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRFbnVtTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZW51bVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VudW0oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0RW51bSgpIHsKICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0RW51bU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gZW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTExfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE51bGwoKSB7CiAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBudWxsXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IG51bGxWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkTnVsbE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIG51bGxWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE51bGxDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsKCkgewogICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0TnVsbE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IG51bGxWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SWYoKSwKICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSwKICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLAogICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLAogICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50KCksCiAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCksCiAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCksCiAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCksCiAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLAogICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKSwKICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTApOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGlmX18gPSBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaWZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNvbnN0X18gPSBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgY29uc3RfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgcHJpdmF0ZV9fID0gUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgcHJpdmF0ZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNsYXNzX19fID0gQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBjbGFzc19fXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnRfXyA9IEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHZvaWRfXyA9IFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHZvaWRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBzdHJpbmdfXyA9IFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNywgc3RyaW5nX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHBhY2thZ2VfXyA9IFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIHBhY2thZ2VfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZW51bV9fID0gRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZW51bV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBudWxsX18gPSBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgbnVsbF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIG90aGVyID0gKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SWYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldENvbnN0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDb25zdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UHJpdmF0ZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Q2xhc3NfKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDbGFzc18oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRWb2lkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UGFja2FnZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UGFja2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TnVsbCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TnVsbCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElGX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldElmKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDT05TVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDb25zdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUklWQVRFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFByaXZhdGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDbGFzc18oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZPSURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Vm9pZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRQYWNrYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RW51bSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOVUxMX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE51bGwoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJZigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVWb2lkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUVudW0oKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVOdWxsKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgYnVpbGQoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcmVzdWx0ID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlmXyA9IGludGVybmFsR2V0SWYoKTsKICAgICAgICAgIHJlc3VsdC5pZl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvbnN0XyA9IGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICAgIHJlc3VsdC5jb25zdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByaXZhdGVfID0gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNsYXNzX18gPSBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgcmVzdWx0LmNsYXNzX18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludF8gPSBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgcmVzdWx0LmludF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnZvaWRfID0gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICByZXN1bHQudm9pZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ18gPSBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBhY2thZ2VfID0gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmVudW1fID0gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICByZXN1bHQuZW51bV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm51bGxfID0gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICByZXN1bHQubnVsbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpZl9fID0gSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5mb3JOdW1iZXIoaWZfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGlmX18uZ2V0S2V5KCksIGlmX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNvbnN0X18gPSBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihjb25zdF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMiwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgY29uc3RfXy5nZXRLZXkoKSwgY29uc3RfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcHJpdmF0ZV9fID0gUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihwcml2YXRlX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgzLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGVfXy5nZXRLZXkoKSwgcHJpdmF0ZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjbGFzc19fXyA9IENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihjbGFzc19fXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDQsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBjbGFzc19fXy5nZXRLZXkoKSwgY2xhc3NfX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludF9fID0gSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uZm9yTnVtYmVyKGludF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoNSwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGludF9fLmdldEtleSgpLCBpbnRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdm9pZF9fID0gVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcih2b2lkX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg2LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHZvaWRfXy5nZXRLZXkoKSwgdm9pZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBzdHJpbmdfXyA9IFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihzdHJpbmdfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDcsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdfXy5nZXRLZXkoKSwgc3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHBhY2thZ2VfXyA9IFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5mb3JOdW1iZXIocGFja2FnZV9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoOCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlX18uZ2V0S2V5KCksIHBhY2thZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZW51bV9fID0gRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihlbnVtX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg5LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGVudW1fXy5nZXRLZXkoKSwgZW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBudWxsX18gPSBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uZm9yTnVtYmVyKG51bGxfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDEwLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIG51bGxfXy5nZXRLZXkoKSwgbnVsbF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIGlmXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpZl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGlmXyA9IGlmXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaWZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSWYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SWZNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SWYoKSB7CiAgICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldElmTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJZk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBpZlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaWZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcklmKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVJZigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dElmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGlmVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJZigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRJZk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY29uc3RfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkgewogICAgICAgIGlmIChjb25zdF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29uc3RfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkgewogICAgICAgIGlmIChjb25zdF8gPT0gbnVsbCkgewogICAgICAgICAgY29uc3RfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWNvbnN0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgY29uc3RfID0gY29uc3RfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBjb25zdF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRDb25zdENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDb25zdCgpIHsKICAgICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Q29uc3RNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENvbnN0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENvbnN0T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGNvbnN0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENvbnN0T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb25zdFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29uc3QoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUNvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Q29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgY29uc3RWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENvbnN0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZENvbnN0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwcml2YXRlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkgewogICAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKSB7CiAgICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICAgIHByaXZhdGVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcHJpdmF0ZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHByaXZhdGVfID0gcHJpdmF0ZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UHJpdmF0ZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UHJpdmF0ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UHJpdmF0ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFByaXZhdGVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFByaXZhdGVNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFByaXZhdGVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcml2YXRlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVByaXZhdGUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgcHJpdmF0ZVZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQcml2YXRlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFByaXZhdGVNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY2xhc3NfXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKSB7CiAgICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzX187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIGNsYXNzX18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWNsYXNzX18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNsYXNzX18gPSBjbGFzc19fLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDbGFzc18oKSB7CiAgICAgICAgcmV0dXJuIGdldENsYXNzX01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDbGFzc19NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBjbGFzc19WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q2xhc3NfT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2xhc3NfVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDbGFzc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Q2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBjbGFzc19WYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENsYXNzXygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpIHsKICAgICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKSB7CiAgICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgICAgaW50XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50Xy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50XyA9IGludF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRJbnQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SW50TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGludFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2b2lkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkgewogICAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZvaWRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKSB7CiAgICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICAgIHZvaWRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdm9pZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHZvaWRfID0gdm9pZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHZvaWRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Vm9pZCgpIHsKICAgICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFZvaWRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJWb2lkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVZvaWQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRWb2lkTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdm9pZFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxWb2lkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKSB7CiAgICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ18gPSBzdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFN0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0U3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBzdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRTdHJpbmdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBzdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHBhY2thZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSB7CiAgICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFja2FnZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpIHsKICAgICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgICAgcGFja2FnZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwYWNrYWdlXy5pc011dGFibGUoKSkgewogICAgICAgICAgcGFja2FnZV8gPSBwYWNrYWdlXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcGFja2FnZV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRQYWNrYWdlKCkgewogICAgICAgIHJldHVybiBnZXRQYWNrYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UGFja2FnZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVQYWNrYWdlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlUGFja2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFBhY2thZ2VNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFBhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFBhY2thZ2UoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnVtXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkgewogICAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVudW1fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKSB7CiAgICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICAgIGVudW1fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZW51bV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGVudW1fID0gZW51bV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGVudW1fOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRFbnVtKCkgewogICAgICAgIHJldHVybiBnZXRFbnVtTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRFbnVtTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRFbnVtTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRW51bU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgZW51bVZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRW51bU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBudWxsXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkgewogICAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGxfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICAgIG51bGxfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbnVsbF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG51bGxfID0gbnVsbF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG51bGxfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0TnVsbCgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldE51bGxNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOdWxsKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXROdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgbnVsbFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxOdWxsKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfUmVxdWlyZWRNZXNzYWdlTWFwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfUmVxdWlyZWRNZXNzYWdlTWFwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfUmVjdXJzaXZlTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9SZWN1cnNpdmVNYXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NsYXNzRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUGFja2FnZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUGFja2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ZvaWRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbjJjb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9mb3JfcHJvdG8yX2xpdCIgKwogICAgICAiZV90ZXN0LnByb3RvXDAyMlwwMzBtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RcIlwyNTAiICsKICAgICAgIlxuXG5cMDA3VGVzdE1hcFwwMjJWXG5cMDI0aW50MzJfdG9faW50MzJfZmllbGRcMDMwXDAwMSBcMDAzKFwwMTMiICsKICAgICAgIjI4Lm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UZXN0TWFwLkludDMiICsKICAgICAgIjJUb0ludDMyRmllbGRFbnRyeVwwMjJYXG5cMDI1aW50MzJfdG9fc3RyaW5nX2ZpIiArCiAgICAgICJlbGRcMDMwXDAwMiBcMDAzKFwwMTMyOS5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzIiArCiAgICAgICJ0TWFwLkludDMyVG9TdHJpbmdGaWVsZEVudHJ5XDAyMlZcblwwMjRpbnQzMl90byIgKwogICAgICAiX2J5dGVzX2ZpZWxkXDAzMFwwMDMgXDAwMyhcMDEzMjgubWFwX2Zvcl9wcm90bzJfbGl0ZSIgKwogICAgICAiX3Rlc3QuVGVzdE1hcC5JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5XDAyMlRcblwwMjMiICsKICAgICAgImludDMyX3RvX2VudW1fZmllbGRcMDMwXDAwNCBcMDAzKFwwMTMyNy5tYXBfZm9yX3Byb3QiICsKICAgICAgIm8yX2xpdGVfdGVzdC5UZXN0TWFwLkludDMyVG9FbnVtRmllbGRFbnQiICsKICAgICAgInJ5XDAyMlpcblwwMjZpbnQzMl90b19tZXNzYWdlX2ZpZWxkXDAzMFwwMDUgXDAwMyhcMDEzMjoubWFwIiArCiAgICAgICJfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5JbnQzMlRvTWVzIiArCiAgICAgICJzYWdlRmllbGRFbnRyeVwwMjJYXG5cMDI1c3RyaW5nX3RvX2ludDMyX2ZpZWxkXDAzMCIgKwogICAgICAiXDAwNiBcMDAzKFwwMTMyOS5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcCIgKwogICAgICAiLlN0cmluZ1RvSW50MzJGaWVsZEVudHJ5XDAyMldcblwwMjRyZXF1aXJlZF9tZXMiICsKICAgICAgInNhZ2VfbWFwXDAzMFwwMTMgXDAwMyhcMDEzMjkubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXMiICsKICAgICAgInQuVGVzdE1hcC5SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeVwwMzJcMDM1XG5cMDE0TWVzIiArCiAgICAgICJzYWdlVmFsdWVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNVwwMzI4XG5cMDI2SW50MzJUb0ludDMyIiArCiAgICAgICJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyIiArCiAgICAgICI4XDAwMVwwMzI5XG5cMDI3SW50MzJUb1N0cmluZ0ZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEiICsKICAgICAgIihcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI4XG5cMDI2SW50MzJUb0J5dGVzRmllIiArCiAgICAgICJsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyIiArCiAgICAgICJkXG5cMDI1SW50MzJUb0VudW1GaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyOlxuIiArCiAgICAgICJcMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyKy5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuIiArCiAgICAgICJUZXN0TWFwLkVudW1WYWx1ZTpcMDAyOFwwMDFcMDMyalxuXDAzMEludDMyVG9NZXNzYWdlRiIgKwogICAgICAiaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyPVxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMi4uIiArCiAgICAgICJtYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlIiArCiAgICAgICJWYWx1ZTpcMDAyOFwwMDFcMDMyOVxuXDAyN1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyKlxuXDAzMU1lc3NhZ2VXIiArCiAgICAgICJpdGhSZXF1aXJlZEZpZWxkc1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDEgXDAwMihcMDA1XDAzMnZcblwwMjdSZXF1IiArCiAgICAgICJpcmVkTWVzc2FnZU1hcEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIySlxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMTMyOy5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuVGVzdE0iICsKICAgICAgImFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM6XDAwMjhcMDAxXCIvXG5cdEVudW0iICsKICAgICAgIlZhbHVlXDAyMlwwMDdcblwwMDNGT09cMDIwXDAwMFwwMjJcMDA3XG5cMDAzQkFSXDAyMFwwMDFcMDIyXDAwN1xuXDAwM0JBWlwwMjBcMDAyXDAyMlwwMDdcblwwMDNRVVhcMDIwIiArCiAgICAgICJcMDAzXCJcMjY1XDAwMVxuXDAyNFRlc3RVbmtub3duRW51bVZhbHVlXDAyMmNcblwwMjRpbnQzMl90b19pIiArCiAgICAgICJudDMyX2ZpZWxkXDAzMFwwMDQgXDAwMyhcMDEzMkUubWFwX2Zvcl9wcm90bzJfbGl0ZV90IiArCiAgICAgICJlc3QuVGVzdFVua25vd25FbnVtVmFsdWUuSW50MzJUb0ludDMyRmllIiArCiAgICAgICJsZEVudHJ5XDAzMjhcblwwMjZJbnQzMlRvSW50MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwiXDM0N1wwMDFcblwwMjBUZXN0UmVjdXJzIiArCiAgICAgICJpdmVNYXBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJeXG5cMDIzcmVjdXJzaXZlX21hcF9mIiArCiAgICAgICJpZWxkXDAzMFwwMDIgXDAwMyhcMDEzMkEubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlRlIiArCiAgICAgICJzdFJlY3Vyc2l2ZU1hcC5SZWN1cnNpdmVNYXBGaWVsZEVudHJ5XDAzMmRcbiIgKwogICAgICAiXDAyNlJlY3Vyc2l2ZU1hcEZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI5XG5cMDA1IiArCiAgICAgICJ2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIqLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5UIiArCiAgICAgICJlc3RSZWN1cnNpdmVNYXA6XDAwMjhcMDAxXCJcMjU3XDAwN1xuXDAxNkJpemFycm9UZXN0TWFwXDAyMl0iICsKICAgICAgIlxuXDAyNGludDMyX3RvX2ludDMyX2ZpZWxkXDAzMFwwMDEgXDAwMyhcMDEzMj8ubWFwX2Zvcl9wIiArCiAgICAgICJyb3RvMl9saXRlX3Rlc3QuQml6YXJyb1Rlc3RNYXAuSW50MzJUb0luIiArCiAgICAgICJ0MzJGaWVsZEVudHJ5XDAyMl9cblwwMjVpbnQzMl90b19zdHJpbmdfZmllbGRcMDMwXDAwMiIgKwogICAgICAiIFwwMDMoXDAxMzJALm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5CaXphcnJvVCIgKwogICAgICAiZXN0TWFwLkludDMyVG9TdHJpbmdGaWVsZEVudHJ5XDAyMl1cblwwMjRpbnQzMl8iICsKICAgICAgInRvX2J5dGVzX2ZpZWxkXDAzMFwwMDMgXDAwMyhcMDEzMj8ubWFwX2Zvcl9wcm90bzJfbGkiICsKICAgICAgInRlX3Rlc3QuQml6YXJyb1Rlc3RNYXAuSW50MzJUb0J5dGVzRmllbGQiICsKICAgICAgIkVudHJ5XDAyMltcblwwMjNpbnQzMl90b19lbnVtX2ZpZWxkXDAzMFwwMDQgXDAwMyhcMDEzMj4ubWFwIiArCiAgICAgICJfZm9yX3Byb3RvMl9saXRlX3Rlc3QuQml6YXJyb1Rlc3RNYXAuSW50IiArCiAgICAgICIzMlRvRW51bUZpZWxkRW50cnlcMDIyYVxuXDAyNmludDMyX3RvX21lc3NhZ2VfZiIgKwogICAgICAiaWVsZFwwMzBcMDA1IFwwMDMoXDAxMzJBLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5CaSIgKwogICAgICAiemFycm9UZXN0TWFwLkludDMyVG9NZXNzYWdlRmllbGRFbnRyeVwwMjJfXG4iICsKICAgICAgIlwwMjVzdHJpbmdfdG9faW50MzJfZmllbGRcMDMwXDAwNiBcMDAzKFwwMTMyQC5tYXBfZm9yX3AiICsKICAgICAgInJvdG8yX2xpdGVfdGVzdC5CaXphcnJvVGVzdE1hcC5TdHJpbmdUb0kiICsKICAgICAgIm50MzJGaWVsZEVudHJ5XDAzMjhcblwwMjZJbnQzMlRvSW50MzJGaWVsZEVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI5XG5cMDI3SW50MyIgKwogICAgICAiMlRvU3RyaW5nRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjhcblwwMjZJbnQzMlRvQnl0ZXNGaWVsZEVudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyN1xuXDAyNUludDMyVG8iICsKICAgICAgIkVudW1GaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAxNDpcMDAyOFwwMDFcMDMyOlxuXDAzMEludDMyVG9NZXNzYWdlRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMjlcblwwMjdTdHJpbmdUb0luIiArCiAgICAgICJ0MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKCIgKwogICAgICAiXDAxNDpcMDAyOFwwMDFcIlwyNDdcdFxuXDAyMlJlc2VydmVkQXNNYXBGaWVsZFwwMjJAXG5cMDAyaWZcMDMwXDAwMSBcMDAzKFwwMTMiICsKICAgICAgIjI0Lm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWEiICsKICAgICAgInBGaWVsZC5JZkVudHJ5XDAyMkZcblwwMDVjb25zdFwwMzBcMDAyIFwwMDMoXDAxMzI3Lm1hcF9mb3JfIiArCiAgICAgICJwcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZC5Db25zIiArCiAgICAgICJ0RW50cnlcMDIySlxuXDAwN3ByaXZhdGVcMDMwXDAwMyBcMDAzKFwwMTMyOS5tYXBfZm9yX3Byb3RvMiIgKwogICAgICAiX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuUHJpdmF0ZUVudCIgKwogICAgICAicnlcMDIyRlxuXDAwNWNsYXNzXDAzMFwwMDQgXDAwMyhcMDEzMjcubWFwX2Zvcl9wcm90bzJfbGl0ZV8iICsKICAgICAgInRlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkLkNsYXNzRW50cnlcMDIyQlxuXDAwM2luIiArCiAgICAgICJ0XDAzMFwwMDUgXDAwMyhcMDEzMjUubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkLkludEVudHJ5XDAyMkRcblwwMDR2b2lkXDAzMFwwMDYgXDAwMyhcMDEzMjYubSIgKwogICAgICAiYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZSIgKwogICAgICAibGQuVm9pZEVudHJ5XDAyMkhcblwwMDZzdHJpbmdcMDMwXDAwNyBcMDAzKFwwMTMyOC5tYXBfZm9yX3AiICsKICAgICAgInJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuU3RyaW4iICsKICAgICAgImdFbnRyeVwwMjJKXG5cMDA3cGFja2FnZVwwMzBcMDEwIFwwMDMoXDAxMzI5Lm1hcF9mb3JfcHJvdG8yIiArCiAgICAgICJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZC5QYWNrYWdlRW50IiArCiAgICAgICJyeVwwMjJEXG5cMDA0ZW51bVwwMzBcdCBcMDAzKFwwMTMyNi5tYXBfZm9yX3Byb3RvMl9saXRlX3QiICsKICAgICAgImVzdC5SZXNlcnZlZEFzTWFwRmllbGQuRW51bUVudHJ5XDAyMkRcblwwMDRudWxsIiArCiAgICAgICJcMDMwXG4gXDAwMyhcMDEzMjYubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydiIgKwogICAgICAiZWRBc01hcEZpZWxkLk51bGxFbnRyeVwwMzIpXG5cMDA3SWZFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIsXG5cbkNvbnN0RW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLlxuXDAxNFByaXZhIiArCiAgICAgICJ0ZUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIiICsKICAgICAgIixcblxuQ2xhc3NFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSgiICsKICAgICAgIlxyOlwwMDI4XDAwMVwwMzIqXG5cMDEwSW50RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzAiICsKICAgICAgIlwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyK1xuXHRWb2lkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLVxuXDAxM1N0cmluZ0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxIiArCiAgICAgICIoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMi5cblwwMTRQYWNrYWdlRW50cnlcMDIyXDAxM1xuIiArCiAgICAgICJcMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyK1xuXHRFbnVtRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyK1xuXHROdSIgKwogICAgICAibGxFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcIiIgKwogICAgICAiXDIxNlwwMjBcblwwMzdSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlXDAyMk1cblwwMDJpIiArCiAgICAgICJmXDAzMFwwMDEgXDAwMyhcMDEzMkEubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5JZkVudHJ5XDAyMlNcblwwMDVjbyIgKwogICAgICAibnN0XDAzMFwwMDIgXDAwMyhcMDEzMkQubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlcyIgKwogICAgICAiZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5Db25zdEVudHJ5XDAyMiIgKwogICAgICAiV1xuXDAwN3ByaXZhdGVcMDMwXDAwMyBcMDAzKFwwMTMyRi5tYXBfZm9yX3Byb3RvMl9saXRlX3QiICsKICAgICAgImVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlByaXYiICsKICAgICAgImF0ZUVudHJ5XDAyMlNcblwwMDVjbGFzc1wwMzBcMDA0IFwwMDMoXDAxMzJELm1hcF9mb3JfcHJvdG8yIiArCiAgICAgICJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsIiArCiAgICAgICJ1ZS5DbGFzc0VudHJ5XDAyMk9cblwwMDNpbnRcMDMwXDAwNSBcMDAzKFwwMTMyQi5tYXBfZm9yX3BybyIgKwogICAgICAidG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bSIgKwogICAgICAiVmFsdWUuSW50RW50cnlcMDIyUVxuXDAwNHZvaWRcMDMwXDAwNiBcMDAzKFwwMTMyQy5tYXBfZm9yX3AiICsKICAgICAgInJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW4iICsKICAgICAgInVtVmFsdWUuVm9pZEVudHJ5XDAyMlVcblwwMDZzdHJpbmdcMDMwXDAwNyBcMDAzKFwwMTMyRS5tYXBfIiArCiAgICAgICJmb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXIiArCiAgICAgICJpdGhFbnVtVmFsdWUuU3RyaW5nRW50cnlcMDIyV1xuXDAwN3BhY2thZ2VcMDMwXDAxMCBcMDAzKCIgKwogICAgICAiXDAxMzJGLm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTSIgKwogICAgICAiYXBGaWVsZFdpdGhFbnVtVmFsdWUuUGFja2FnZUVudHJ5XDAyMlFcblwwMDRlbnUiICsKICAgICAgIm1cMDMwXHQgXDAwMyhcMDEzMkMubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5FbnVtRW50cnlcMDIyUVxuXDAwNCIgKwogICAgICAibnVsbFwwMzBcbiBcMDAzKFwwMTMyQy5tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3QuUmUiICsKICAgICAgInNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLk51bGxFbnRyeVwwMzIiICsKICAgICAgIm9cblwwMDdJZkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjJEIiArCiAgICAgICIubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGIiArCiAgICAgICJpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwwMzJyXG5cbkNvbnMiICsKICAgICAgInRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJTXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyRC5tYXAiICsKICAgICAgIl9mb3JfcHJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQiICsKICAgICAgIldpdGhFbnVtVmFsdWUuU2FtcGxlRW51bTpcMDAyOFwwMDFcMDMydFxuXDAxNFByaXZhdGVFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjJELm1hcF9mIiArCiAgICAgICJvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpIiArCiAgICAgICJ0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwwMzJyXG5cbkNsYXNzRW50cnkiICsKICAgICAgIlwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJTXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyRC5tYXBfZm9yX3AiICsKICAgICAgInJvdG8yX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW4iICsKICAgICAgInVtVmFsdWUuU2FtcGxlRW51bTpcMDAyOFwwMDFcMDMycFxuXDAxMEludEVudHJ5XDAyMlwwMTNcblwwMDNrZSIgKwogICAgICAieVwwMzBcMDAxIFwwMDEoXHRcMDIyU1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MkQubWFwX2Zvcl9wcm90bzJfIiArCiAgICAgICJsaXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1IiArCiAgICAgICJlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMnFcblx0Vm9pZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxIiArCiAgICAgICIoXHRcMDIyU1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MkQubWFwX2Zvcl9wcm90bzJfbGl0ZV8iICsKICAgICAgInRlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW0iICsKICAgICAgInBsZUVudW06XDAwMjhcMDAxXDAzMnNcblwwMTNTdHJpbmdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjIiICsKICAgICAgIlNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjJELm1hcF9mb3JfcHJvdG8yX2xpdGVfdGVzIiArCiAgICAgICJ0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlIiArCiAgICAgICJFbnVtOlwwMDI4XDAwMVwwMzJ0XG5cMDE0UGFja2FnZUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlNcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MkQubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LiIgKwogICAgICAiUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbiIgKwogICAgICAidW06XDAwMjhcMDAxXDAzMnFcblx0RW51bUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlNcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE2MkQubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4IiArCiAgICAgICJcMDAxXDAzMnFcblx0TnVsbEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDE2MkQubWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0LlJlc2VydmVkQXMiICsKICAgICAgIk1hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwiXDAzMlxuXG4iICsKICAgICAgIlNhbXBsZUVudW1cMDIyXDAwNVxuXDAwMUFcMDIwXDAwMFwwMjJcMDA1XG5cMDAxQlwwMjBcMDAxQihcblxybWFwX2xpdGVfdGVzIiArCiAgICAgICJ0QlwwMjVNYXBGb3JQcm90bzJUZXN0UHJvdG9IXDAwMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJJbnQzMlRvSW50MzJGaWVsZCIsICJJbnQzMlRvU3RyaW5nRmllbGQiLCAiSW50MzJUb0J5dGVzRmllbGQiLCAiSW50MzJUb0VudW1GaWVsZCIsICJJbnQzMlRvTWVzc2FnZUZpZWxkIiwgIlN0cmluZ1RvSW50MzJGaWVsZCIsICJSZXF1aXJlZE1lc3NhZ2VNYXAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0TWFwX1JlcXVpcmVkTWVzc2FnZU1hcEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdE1hcF9SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkludDMyVG9JbnQzMkZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfSW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgIlJlY3Vyc2l2ZU1hcEZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfUmVjdXJzaXZlTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfUmVjdXJzaXZlTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9SZWN1cnNpdmVNYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW50MzJUb0ludDMyRmllbGQiLCAiSW50MzJUb1N0cmluZ0ZpZWxkIiwgIkludDMyVG9CeXRlc0ZpZWxkIiwgIkludDMyVG9FbnVtRmllbGQiLCAiSW50MzJUb01lc3NhZ2VGaWVsZCIsICJTdHJpbmdUb0ludDMyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSWYiLCAiQ29uc3QiLCAiUHJpdmF0ZSIsICJDbGFzc18iLCAiSW50IiwgIlZvaWQiLCAiU3RyaW5nIiwgIlBhY2thZ2UiLCAiRW51bSIsICJOdWxsIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JZkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NsYXNzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUGFja2FnZUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUGFja2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUGFja2FnZUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJJZiIsICJDb25zdCIsICJQcml2YXRlIiwgIkNsYXNzXyIsICJJbnQiLCAiVm9pZCIsICJTdHJpbmciLCAiUGFja2FnZSIsICJFbnVtIiwgIk51bGwiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUGFja2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEA2pKnz1zNCQBczQkAHwAAAG1hcF9saXRlX3Rlc3QvTWFwVGVzdFByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgbWFwX2xpdGVfdGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBNYXBUZXN0UHJvdG8gewogIHByaXZhdGUgTWFwVGVzdFByb3RvKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2xpdGVfdGVzdC5UZXN0TWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVpbnQzMlRvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1VpbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VWludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRVaW50MzJUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRVaW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQ2NFRvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQ2NFRvSW50MzJGaWVsZCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDY0VG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQ2NFRvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDY0VG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQ2NFRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDY0VG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9saXRlX3Rlc3QuVGVzdE1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNYXAgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX2xpdGVfdGVzdC5UZXN0TWFwKQogICAgICBUZXN0TWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWFwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNYXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgIGNhc2UgODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIG1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWV9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEVudW1WYWx1ZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgRk9PKDApLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVIoMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBWigyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlFVWCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgUVVYKDMpLAogICAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfVkFMVUUgPSAxOwogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfVkFMVUUgPSAyOwogICAgICAvKioKICAgICAgICogPGNvZGU+UVVYID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBRVVhfVkFMVUUgPSAzOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBFbnVtVmFsdWUgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIEVudW1WYWx1ZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gRk9POwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gQkFSOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFaOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gUVVYOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bVZhbHVlPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgRW51bVZhbHVlPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bVZhbHVlPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgRW51bVZhbHVlIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBFbnVtVmFsdWUuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW51bVZhbHVlW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIEVudW1WYWx1ZSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgICAgIHJldHVybiBVTlJFQ09HTklaRUQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUpCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBNZXNzYWdlVmFsdWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBpbnQgZ2V0VmFsdWUoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNZXNzYWdlVmFsdWUgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgICAgTWVzc2FnZVZhbHVlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTWVzc2FnZVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTWVzc2FnZVZhbHVlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VWYWx1ZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAodmFsdWVfICE9IDApIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICh2YWx1ZV8gIT0gMCkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBvdGhlciA9IChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgb2JqOwoKICAgICAgICBpZiAoZ2V0VmFsdWUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZBTFVFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRWYWx1ZSgpOwogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWV9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGJ1aWxkKCkgewogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5nZXRWYWx1ZSgpICE9IDApIHsKICAgICAgICAgICAgc2V0VmFsdWUob3RoZXIuZ2V0VmFsdWUoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgdmFsdWVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5pbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VmFsdWUoaW50IHZhbHVlKSB7CgogICAgICAgICAgdmFsdWVfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5pbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVZhbHVlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TWVzc2FnZVZhbHVlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE1lc3NhZ2VWYWx1ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VWYWx1ZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VWYWx1ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX1NUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX0VOVU1fRklFTERfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvRW51bUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4gaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUsIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGdldEludDMyVG9FbnVtRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4KICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9NZXNzYWdlRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFVpbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfVWludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdWludDMyVG9JbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKHVpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVpbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1aW50MzJUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRVaW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVWludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0VWludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0VWludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVaW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRVaW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQ2NF9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50NjRUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDY0VG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50NjRUb0ludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQ2NFRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDY0VG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50NjRUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50NjRUb0ludDMyRmllbGQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50NjRUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDY0VG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50NjRUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQ2NFRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludDY0VG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSwKICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLAogICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLAogICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBVaW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSwKICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpbnQzMlRvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBpbnQzMlRvU3RyaW5nRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fID0gSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGludDMyVG9CeXRlc0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0VudW1GaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXyA9IEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGludDMyVG9NZXNzYWdlRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfXyA9IFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgc3RyaW5nVG9JbnQzMkZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB1aW50MzJUb0ludDMyRmllbGRfXyA9IFVpbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNywgdWludDMyVG9JbnQzMkZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDY0VG9JbnQzMkZpZWxkX18gPSBJbnQ2NFRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgaW50NjRUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBvdGhlciA9IChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQ2NFRvSW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQ2NF9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQ2NFRvSW50MzJGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfbGl0ZV90ZXN0LlRlc3RNYXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfbGl0ZV90ZXN0LlRlc3RNYXApCiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIGJ1aWxkKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvU3RyaW5nRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvU3RyaW5nRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0J5dGVzRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvRW51bUZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmJ1aWxkKEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdUb0ludDMyRmllbGRfID0gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51aW50MzJUb0ludDMyRmllbGRfID0gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC51aW50MzJUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQ2NFRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50NjRUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0VudW1GaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18uZ2V0S2V5KCksIHN0cmluZ1RvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1aW50MzJUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFVpbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHVpbnQzMlRvSW50MzJGaWVsZF9fLmdldEtleSgpLCB1aW50MzJUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW50NjRUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQ2NFRvSW50MzJGaWVsZF9fLmdldEtleSgpLCBpbnQ2NFRvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0ludDMyRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF8gPSBpbnQzMlRvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9TdHJpbmdGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF8gPSBpbnQzMlRvU3RyaW5nRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0J5dGVzRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvQnl0ZXNGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkXyA9IGludDMyVG9CeXRlc0ZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9FbnVtRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9FbnVtRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0VudW1GaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfID0gaW50MzJUb0VudW1GaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgICBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkSW50MzJUb0VudW1GaWVsZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZFZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0VudW1GaWVsZFZhbHVlKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0VudW1GaWVsZFZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBidWlsZChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgeyByZXR1cm4gKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIgaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlciA9IG5ldyBJbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlcj4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihpbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2xpdGVfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyIHB1dEludDMyVG9NZXNzYWdlRmllbGRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIHsKICAgICAgICAgIGVudHJ5ID0gKChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoc3RyaW5nVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghc3RyaW5nVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkXyA9IHN0cmluZ1RvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdWludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmICh1aW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVWludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1aW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHVpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgdWludDMyVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVWludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdWludDMyVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgdWludDMyVG9JbnQzMkZpZWxkXyA9IHVpbnQzMlRvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVaW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVaW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVaW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0VWludDMyVG9JbnQzMkZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVpbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVaW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VWludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVaW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50NjRUb0ludDMyRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQ2NFRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50NjRUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50NjRUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDY0VG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDY0VG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQ2NFRvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50NjRUb0ludDMyRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQ2NFRvSW50MzJGaWVsZF8gPSBpbnQ2NFRvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDY0VG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDY0VG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50NjRUb0ludDMyRmllbGQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDY0VG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDY0VG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDY0VG9JbnQzMkZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50NjRUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50NjRUb0ludDMyRmllbGRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50NjRUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50NjRUb0ludDMyRmllbGQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQ2NFRvSW50MzJGaWVsZCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDY0VG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2xpdGVfdGVzdC5UZXN0TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfbGl0ZV90ZXN0LlRlc3RNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfbGl0ZV90ZXN0LlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lm1hcF9saXRlX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE1lc3NhZ2UuCiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgZ2V0T3B0aW9uYWxNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwT3JCdWlsZGVyIGdldE9wdGlvbmFsTWVzc2FnZU9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFVzZWQgdG8gdGVzdCB0aGF0IGEgbmVzdGVkIGJ1aWxkZXIgY29udGFpbmluZyBtYXAgZmllbGRzIHdpbGwgcHJvcGVybHkKICAgKiBwcm9wYWdhdGUgdGhlIG9uQ2hhbmdlIGV2ZW50IGFuZCBtYXJrIGl0cyBwYXJlbnQgZGlydHkgd2hlbiBhIGNoYW5nZQogICAqIGlzIG1hZGUgdG8gYSBtYXAgZmllbGQuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfbGl0ZV90ZXN0LlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb259CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbikKICAgICAgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgb3B0aW9uYWxNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+Lm1hcF9saXRlX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgZ2V0T3B0aW9uYWxNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlXyA9PSBudWxsID8gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gb3RoZXIgPSAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVXNlZCB0byB0ZXN0IHRoYXQgYSBuZXN0ZWQgYnVpbGRlciBjb250YWluaW5nIG1hcCBmaWVsZHMgd2lsbCBwcm9wZXJseQogICAgICogcHJvcGFnYXRlIHRoZSBvbkNoYW5nZSBldmVudCBhbmQgbWFyayBpdHMgcGFyZW50IGRpcnR5IHdoZW4gYSBjaGFuZ2UKICAgICAqIGlzIG1hZGUgdG8gYSBtYXAgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfbGl0ZV90ZXN0LlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb259CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfbGl0ZV90ZXN0LlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pCiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gYnVpbGQoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcmVzdWx0ID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE1lc3NhZ2VfID0gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgb3B0aW9uYWxNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwT3JCdWlsZGVyPiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgZ2V0T3B0aW9uYWxNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlXyA9PSBudWxsID8gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTWVzc2FnZShtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTWVzc2FnZSgKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxNZXNzYWdlKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfICE9IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lm1hcF9saXRlX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwT3JCdWlsZGVyIGdldE9wdGlvbmFsTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOm1hcF9saXRlX3Rlc3QuVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2xpdGVfdGVzdC5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEJpemFycm9UZXN0TWFwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9saXRlX3Rlc3QuQml6YXJyb1Rlc3RNYXApCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9NZXNzYWdlRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIGEgZGVjb3kgb2YgVGVzdE1hcCBmb3IgdGVzdGluZyBwYXJzaW5nIGVycm9ycwogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2xpdGVfdGVzdC5CaXphcnJvVGVzdE1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJpemFycm9UZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuQml6YXJyb1Rlc3RNYXApCiAgICAgIEJpemFycm9UZXN0TWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBCaXphcnJvVGVzdE1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBCaXphcnJvVGVzdE1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEJpemFycm9UZXN0TWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEJpemFycm9UZXN0TWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX1NUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvRW51bUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLAogICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSwKICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLAogICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSwKICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSwKICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpbnQzMlRvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBpbnQzMlRvU3RyaW5nRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9CeXRlc0ZpZWxkX18gPSBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgaW50MzJUb0J5dGVzRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18gPSBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBpbnQzMlRvRW51bUZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18gPSBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHN0cmluZ1RvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgb3RoZXIgPSAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19TVFJJTkdfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19CWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19FTlVNX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGEgZGVjb3kgb2YgVGVzdE1hcCBmb3IgdGVzdGluZyBwYXJzaW5nIGVycm9ycwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2xpdGVfdGVzdC5CaXphcnJvVGVzdE1hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuQml6YXJyb1Rlc3RNYXApCiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXBPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGJ1aWxkKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9JbnQzMkZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9CeXRlc0ZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0VudW1GaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9NZXNzYWdlRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb01lc3NhZ2VGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0J5dGVzRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9FbnVtRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgc3RyaW5nVG9JbnQzMkZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGludDMyVG9JbnQzMkZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvU3RyaW5nRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gaW50MzJUb1N0cmluZ0ZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0J5dGVzRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnQzMlRvQnl0ZXNGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0VudW1GaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvRW51bUZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0VudW1GaWVsZF8gPSBpbnQzMlRvRW51bUZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9NZXNzYWdlRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGludDMyVG9NZXNzYWdlRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghc3RyaW5nVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkXyA9IHN0cmluZ1RvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qml6YXJyb1Rlc3RNYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Qml6YXJyb1Rlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCaXphcnJvVGVzdE1hcCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJpemFycm9UZXN0TWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJpemFycm9UZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFJlc2VydmVkQXNNYXBGaWVsZE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldElmQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSWYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJZk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENvbnN0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zQ29uc3QoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UHJpdmF0ZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UHJpdmF0ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFByaXZhdGVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc18oKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q2xhc3NfTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q2xhc3NfT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFZvaWRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFZvaWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0U3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRFbnVtKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bU1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW51bU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGwoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TnVsbE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVXNlZCB0byB0ZXN0IHRoYXQgamF2YSByZXNlcnZlZCB3b3JkcyBjYW4gYmUgdXNlZCBhcyBwcm90b2J1ZiBmaWVsZCBuYW1lcwogICAqIE5vdCBhbGwgcmVzZXJ2ZWQgd29yZHMgYXJlIHRlc3RlZCAodG8gYXZvaWQgYmxvYXQpIGJ1dCBpbnN0ZWFkIGFuIGFyYml0cmFyeQogICAqIHN1YnNldCBvZiB0aGVtIGNob3NlbiB0byBjb3ZlciB2YXJpb3VzIGtleXdvcmQgY2F0ZWdvcmllcyBsaWtlCiAgICogdHlwZSwgbW9kaWZpZXIsIGRlY2xhcmF0aW9uLCBldGMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlc2VydmVkQXNNYXBGaWVsZCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgICAgUmVzZXJ2ZWRBc01hcEZpZWxkT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBSZXNlcnZlZEFzTWFwRmllbGQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUmVzZXJ2ZWRBc01hcEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUmVzZXJ2ZWRBc01hcEZpZWxkKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFJlc2VydmVkQXNNYXBGaWVsZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgY2FzZSA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpOwogICAgICAgIGNhc2UgMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSWZEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgIGlmIChpZl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGlmXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJZigpIHsKICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SWZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTlNUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDb25zdERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY29uc3RfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gY29uc3RfOwogICAgfQogICAgcHVibGljIGludCBnZXRDb25zdENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0KCkgewogICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q29uc3RNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJVkFURV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwcml2YXRlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0UHJpdmF0ZSgpIHsKICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgfQogICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFByaXZhdGUoKSB7CiAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NsYXNzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldENsYXNzXygpIHsKICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBjbGFzc19fOwogICAgfQogICAgcHVibGljIGludCBnZXRDbGFzc19Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfKCkgewogICAgICByZXR1cm4gZ2V0Q2xhc3NfTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENsYXNzX01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50KCkgewogICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50KCkgewogICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZPSURfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFZvaWREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdm9pZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFZvaWQoKSB7CiAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRWb2lkKCkgewogICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFZvaWRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFN0cmluZygpIHsKICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdfOwogICAgfQogICAgcHVibGljIGludCBnZXRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tBR0VfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2FnZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSB7CiAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQYWNrYWdlKCkgewogICAgICByZXR1cm4gZ2V0UGFja2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFBhY2thZ2VNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9FbnVtRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudW1fOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRFbnVtKCkgewogICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZW51bV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RW51bSgpIHsKICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVMTF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE51bGxEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX051bGxFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE51bGwoKSB7CiAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBudWxsXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TnVsbENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TnVsbCgpIHsKICAgICAgcmV0dXJuIGdldE51bGxNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TnVsbE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE51bGxPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SWYoKSwKICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSwKICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLAogICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLAogICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50KCksCiAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCksCiAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCksCiAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCksCiAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLAogICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKSwKICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTApOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGlmX18gPSBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaWZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNvbnN0X18gPSBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgY29uc3RfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgcHJpdmF0ZV9fID0gUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgcHJpdmF0ZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNsYXNzX19fID0gQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBjbGFzc19fXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnRfXyA9IEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHZvaWRfXyA9IFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHZvaWRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBzdHJpbmdfXyA9IFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNywgc3RyaW5nX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHBhY2thZ2VfXyA9IFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIHBhY2thZ2VfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZW51bV9fID0gRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZW51bV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBudWxsX18gPSBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgbnVsbF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBvdGhlciA9IChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SWYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldENvbnN0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDb25zdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UHJpdmF0ZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Q2xhc3NfKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDbGFzc18oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRWb2lkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UGFja2FnZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UGFja2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TnVsbCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TnVsbCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElGX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldElmKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDT05TVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDb25zdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUklWQVRFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFByaXZhdGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDbGFzc18oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZPSURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Vm9pZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRQYWNrYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RW51bSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOVUxMX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE51bGwoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVXNlZCB0byB0ZXN0IHRoYXQgamF2YSByZXNlcnZlZCB3b3JkcyBjYW4gYmUgdXNlZCBhcyBwcm90b2J1ZiBmaWVsZCBuYW1lcwogICAgICogTm90IGFsbCByZXNlcnZlZCB3b3JkcyBhcmUgdGVzdGVkICh0byBhdm9pZCBibG9hdCkgYnV0IGluc3RlYWQgYW4gYXJiaXRyYXJ5CiAgICAgKiBzdWJzZXQgb2YgdGhlbSBjaG9zZW4gdG8gY292ZXIgdmFyaW91cyBrZXl3b3JkIGNhdGVnb3JpZXMgbGlrZQogICAgICogdHlwZSwgbW9kaWZpZXIsIGRlY2xhcmF0aW9uLCBldGMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkKQogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbnVtKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGJ1aWxkKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaWZfID0gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgcmVzdWx0LmlmXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY29uc3RfID0gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgcmVzdWx0LmNvbnN0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8gPSBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIHJlc3VsdC5wcml2YXRlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXyA9IGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50XyA9IGludGVybmFsR2V0SW50KCk7CiAgICAgICAgICByZXN1bHQuaW50Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudm9pZF8gPSBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICAgIHJlc3VsdC52b2lkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXyA9IGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8gPSBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrYWdlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZW51bV8gPSBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIHJlc3VsdC5lbnVtXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubnVsbF8gPSBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIHJlc3VsdC5udWxsXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SWYoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENvbnN0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFByaXZhdGUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDbGFzc18oKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Vm9pZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRQYWNrYWdlKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVudW0oKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TnVsbCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGlmX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaWZfXy5nZXRLZXkoKSwgaWZfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjb25zdF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGNvbnN0X18uZ2V0S2V5KCksIGNvbnN0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcHJpdmF0ZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBwcml2YXRlX18uZ2V0S2V5KCksIHByaXZhdGVfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjbGFzc19fXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGNsYXNzX19fLmdldEtleSgpLCBjbGFzc19fXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludF9fLmdldEtleSgpLCBpbnRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB2b2lkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHZvaWRfXy5nZXRLZXkoKSwgdm9pZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHN0cmluZ19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nX18uZ2V0S2V5KCksIHN0cmluZ19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHBhY2thZ2VfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgcGFja2FnZV9fLmdldEtleSgpLCBwYWNrYWdlX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgZW51bV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBlbnVtX18uZ2V0S2V5KCksIGVudW1fXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBudWxsX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG51bGxfXy5nZXRLZXkoKSwgbnVsbF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpZl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpZl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKSB7CiAgICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgICBpZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaWZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpZl8gPSBpZl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldElmQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmKCkgewogICAgICAgIHJldHVybiBnZXRJZk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJZk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcklmKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSWYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJZigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJZigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBjb25zdF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb25zdF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKSB7CiAgICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgICBjb25zdF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghY29uc3RfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjb25zdF8gPSBjb25zdF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENvbnN0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0KCkgewogICAgICAgIHJldHVybiBnZXRDb25zdE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDb25zdE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVDb25zdCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxDb25zdCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwcml2YXRlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkgewogICAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKSB7CiAgICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICAgIHByaXZhdGVfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcHJpdmF0ZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHByaXZhdGVfID0gcHJpdmF0ZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UHJpdmF0ZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UHJpdmF0ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFByaXZhdGVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclByaXZhdGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlUHJpdmF0ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsUHJpdmF0ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgICBjbGFzc19fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjbGFzc19fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjbGFzc19fID0gY2xhc3NfXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY2xhc3NfXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfKCkgewogICAgICAgIHJldHVybiBnZXRDbGFzc19NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDbGFzc19PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDbGFzc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Q2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxDbGFzc18oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50KCkgewogICAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpIHsKICAgICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgICBpbnRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnRfID0gaW50Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2b2lkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkgewogICAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZvaWRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKSB7CiAgICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICAgIHZvaWRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdm9pZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHZvaWRfID0gdm9pZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHZvaWRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Vm9pZCgpIHsKICAgICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFZvaWRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZvaWQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlVm9pZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Vm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVm9pZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdfID0gc3RyaW5nXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gc3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpIHsKICAgICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkgewogICAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICBwYWNrYWdlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXBhY2thZ2VfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBwYWNrYWdlXyA9IHBhY2thZ2VfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFBhY2thZ2UoKSB7CiAgICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQYWNrYWdlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVBhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFBhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFBhY2thZ2UoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnVtXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkgewogICAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVudW1fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKSB7CiAgICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICAgIGVudW1fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghZW51bV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGVudW1fID0gZW51bV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGVudW1fOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtKCkgewogICAgICAgIHJldHVybiBnZXRFbnVtTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEVudW1PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxFbnVtKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpIHsKICAgICAgICBpZiAobnVsbF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkgewogICAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgICBudWxsXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW51bGxfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBudWxsXyA9IG51bGxfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBudWxsXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bGxDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldE51bGwoKSB7CiAgICAgICAgcmV0dXJuIGdldE51bGxNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXROdWxsTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOdWxsKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU51bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE51bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE51bGwoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJZigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SWZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SWZWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZlZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldElmVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q29uc3RNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q29uc3RWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENvbnN0VmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNQcml2YXRlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UHJpdmF0ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQcml2YXRlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFByaXZhdGVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFByaXZhdGVWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDbGFzc19NYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19WYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc19WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc19WYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q2xhc3NfVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJbnRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnRWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnRWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Vm9pZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFZvaWRWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFZvaWRWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFZvaWRWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1N0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0U3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRTdHJpbmdNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFBhY2thZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrYWdlVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrYWdlVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZVZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0VudW0oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRFbnVtKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEVudW1NYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0RW51bU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bVZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW51bVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TnVsbFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE51bGxWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkKICAgICAgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgY2FzZSA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpOwogICAgICAgIGNhc2UgMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5jbGFzcywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIG1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBTYW1wbGVFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+QSA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQSgwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEIoMSksCiAgICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJfVkFMVUUgPSAxOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBTYW1wbGVFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBTYW1wbGVFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBBOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gQjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFNhbXBsZUVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBTYW1wbGVFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8U2FtcGxlRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFNhbXBsZUVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFNhbXBsZUVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2FtcGxlRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBTYW1wbGVFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgU2FtcGxlRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtKQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJZkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaWZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaWZfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gaWZWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRJZk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGlmVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRJZkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SWYoKSB7CiAgICAgIHJldHVybiBnZXRJZk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldElmTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldElmT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpZlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldElmVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRJZlZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZlZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SWZWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJZlZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT05TVF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Db25zdEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgIGlmIChjb25zdF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbnN0XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGNvbnN0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBjb25zdFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENvbnN0KCkgewogICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENvbnN0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBjb25zdFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdFZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0Q29uc3RWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q29uc3RWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENvbnN0VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJVkFURV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwcml2YXRlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0UHJpdmF0ZSgpIHsKICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByaXZhdGVfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gcHJpdmF0ZVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFByaXZhdGVNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBwcml2YXRlVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UHJpdmF0ZSgpIHsKICAgICAgcmV0dXJuIGdldFByaXZhdGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFByaXZhdGVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gcHJpdmF0ZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldFByaXZhdGVWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQcml2YXRlVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UHJpdmF0ZVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY2xhc3NfXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNsYXNzX187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBjbGFzc19WYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBjbGFzc19WYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzXygpIHsKICAgICAgcmV0dXJuIGdldENsYXNzX01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzX01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gY2xhc3NfVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX1ZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc19WYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldENsYXNzX1ZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc19WYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDbGFzc19WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlRfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludCgpIHsKICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gaW50VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgaW50VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SW50KCkgewogICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEludE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludE1hcCgKICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpbnRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBpbnRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludFZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0SW50VmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZPSURfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFZvaWREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdm9pZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFZvaWQoKSB7CiAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZvaWRWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRWb2lkTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdm9pZFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFZvaWQoKSB7CiAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdm9pZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZvaWRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRWb2lkVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Vm9pZFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFZvaWRWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZFZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBzdHJpbmdWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBzdHJpbmdWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZygpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1ZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ1ZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLQUdFX0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUGFja2FnZUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHBhY2thZ2VfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcGFja2FnZV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHBhY2thZ2VWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQYWNrYWdlKCkgewogICAgICByZXR1cm4gZ2V0UGFja2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFBhY2thZ2VNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2FnZVZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0UGFja2FnZVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFBhY2thZ2VWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrYWdlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudW1fOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRFbnVtKCkgewogICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gZW51bV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBlbnVtVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkRW51bU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGVudW1WYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRFbnVtKCkgewogICAgICByZXR1cm4gZ2V0RW51bU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0RW51bU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEVudW1PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1WYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bVZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RW51bVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEVudW1WYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRFbnVtVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTnVsbERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBudWxsXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TnVsbCgpIHsKICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG51bGxfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gbnVsbFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBudWxsVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXROdWxsQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldE51bGwoKSB7CiAgICAgIHJldHVybiBnZXROdWxsTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0TnVsbE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG51bGxWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXROdWxsVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXROdWxsVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVsbFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVsbFZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldElmKCksCiAgICAgICAgICBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCksCiAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKSwKICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKSwKICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLAogICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLAogICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLAogICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLAogICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKSwKICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCksCiAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpZl9fID0gSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGlmX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBjb25zdF9fID0gQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGNvbnN0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHByaXZhdGVfXyA9IFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIHByaXZhdGVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBjbGFzc19fXyA9IENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgY2xhc3NfX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50X18gPSBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGludF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB2b2lkX18gPSBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCB2b2lkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgc3RyaW5nX18gPSBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIHN0cmluZ19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBwYWNrYWdlX18gPSBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4LCBwYWNrYWdlX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGVudW1fXyA9IEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGVudW1fXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbnVsbF9fID0gTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIG51bGxfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBvdGhlciA9IChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SWYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldElmKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRDb25zdCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFByaXZhdGUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFByaXZhdGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldENsYXNzXygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q2xhc3NfKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Vm9pZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Vm9pZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFBhY2thZ2UoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEVudW0oKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVudW0oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE51bGwoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE51bGwoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJRl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJZigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ09OU1RfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Q29uc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJJVkFURV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRQcml2YXRlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0xBU1NfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Q2xhc3NfKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWT0lEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFZvaWQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0UGFja2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBFTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEVudW0oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTlVMTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXROdWxsKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkKICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbnVtKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmNsYXNzLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgYnVpbGQoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcmVzdWx0ID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlmXyA9IGludGVybmFsR2V0SWYoKTsKICAgICAgICAgIHJlc3VsdC5pZl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvbnN0XyA9IGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICAgIHJlc3VsdC5jb25zdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByaXZhdGVfID0gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNsYXNzX18gPSBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgcmVzdWx0LmNsYXNzX18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludF8gPSBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgcmVzdWx0LmludF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnZvaWRfID0gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICByZXN1bHQudm9pZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ18gPSBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBhY2thZ2VfID0gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmVudW1fID0gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICByZXN1bHQuZW51bV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm51bGxfID0gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICByZXN1bHQubnVsbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaWZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpZl9fLmdldEtleSgpLCBpZl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNvbnN0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY29uc3RfXy5nZXRLZXkoKSwgY29uc3RfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBwcml2YXRlX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHByaXZhdGVfXy5nZXRLZXkoKSwgcHJpdmF0ZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNsYXNzX19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY2xhc3NfX18uZ2V0S2V5KCksIGNsYXNzX19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50X18uZ2V0S2V5KCksIGludF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHZvaWRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgdm9pZF9fLmdldEtleSgpLCB2b2lkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgc3RyaW5nX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBzdHJpbmdfXy5nZXRLZXkoKSwgc3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcGFja2FnZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBwYWNrYWdlX18uZ2V0S2V5KCksIHBhY2thZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBlbnVtX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGVudW1fXy5nZXRLZXkoKSwgZW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG51bGxfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbnVsbF9fLmdldEtleSgpLCBudWxsX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIGlmXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpZl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGlmXyA9IGlmXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaWZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldElmKCkgewogICAgICAgIHJldHVybiBnZXRJZk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SWZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBpZlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldElmVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRJZlZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRJZlZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldElmVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldElmVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySWYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVJZigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBpZlZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbElmKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVJZlZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dElmVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSWZWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBjb25zdF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb25zdF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKSB7CiAgICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgICBjb25zdF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghY29uc3RfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjb25zdF8gPSBjb25zdF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENvbnN0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDb25zdCgpIHsKICAgICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldENvbnN0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENvbnN0T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb25zdFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0Q29uc3RWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0Q29uc3RWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRDb25zdFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDb25zdFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldENvbnN0VmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlQ29uc3QoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Q29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgY29uc3RWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxDb25zdCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlQ29uc3RWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDb25zdFZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENvbnN0VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcHJpdmF0ZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpIHsKICAgICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwcml2YXRlXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkgewogICAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgICBwcml2YXRlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXByaXZhdGVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBwcml2YXRlXyA9IHByaXZhdGVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBwcml2YXRlXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRQcml2YXRlKCkgewogICAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFByaXZhdGVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFByaXZhdGVNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gcHJpdmF0ZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByaXZhdGVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UHJpdmF0ZVZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRQcml2YXRlVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRQcml2YXRlVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcml2YXRlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVByaXZhdGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVQcml2YXRlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFByaXZhdGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQcml2YXRlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFByaXZhdGVNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlUHJpdmF0ZVZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQcml2YXRlVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFByaXZhdGVWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgICBjbGFzc19fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjbGFzc19fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjbGFzc19fID0gY2xhc3NfXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY2xhc3NfXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldENsYXNzXygpIHsKICAgICAgICByZXR1cm4gZ2V0Q2xhc3NfTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDbGFzc19NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gY2xhc3NfVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRDbGFzc19WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0Q2xhc3NfVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0Q2xhc3NfVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDbGFzc19WYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDbGFzc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVDbGFzc18oKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENsYXNzXygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVDbGFzc19WYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Q2xhc3NfVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENsYXNzX1ZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpIHsKICAgICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKSB7CiAgICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgICAgaW50XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50Xy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50XyA9IGludF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SW50KCkgewogICAgICAgIHJldHVybiBnZXRJbnRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRJbnRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEludFZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRJbnRWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0SW50VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50VmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBpbnRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEludE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUludFZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50VmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnRWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdm9pZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpIHsKICAgICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2b2lkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkgewogICAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgICB2b2lkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXZvaWRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB2b2lkXyA9IHZvaWRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB2b2lkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFZvaWRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRWb2lkKCkgewogICAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFZvaWRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRWb2lkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdm9pZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRWb2lkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZvaWRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0Vm9pZFZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRWb2lkVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRWb2lkVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZvaWRWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJWb2lkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVZvaWQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVWb2lkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFZvaWQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxWb2lkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlVm9pZFZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRWb2lkVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFZvaWRWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdfID0gc3RyaW5nXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gc3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0U3RyaW5nKCkgewogICAgICAgIHJldHVybiBnZXRTdHJpbmdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0U3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gc3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFN0cmluZ1ZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRTdHJpbmdWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFN0cmluZ1ZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkU3RyaW5nTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZVN0cmluZ1ZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFN0cmluZ1ZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZ1ZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICAgIHBhY2thZ2VfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcGFja2FnZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHBhY2thZ2VfID0gcGFja2FnZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFBhY2thZ2UoKSB7CiAgICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UGFja2FnZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFja2FnZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRQYWNrYWdlVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldFBhY2thZ2VWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFBhY2thZ2VWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZVZhbHVlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRQYWNrYWdlTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFBhY2thZ2UoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVQYWNrYWdlVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFBhY2thZ2VWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsUGFja2FnZVZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpIHsKICAgICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbnVtXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkgewogICAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnVtXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVudW1fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBlbnVtXyA9IGVudW1fLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBlbnVtXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldEVudW0oKSB7CiAgICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRFbnVtTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRFbnVtTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gZW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEVudW1PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRFbnVtVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEVudW1WYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RW51bVZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRFbnVtVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bVZhbHVlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkRW51bU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVFbnVtVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RW51bVZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG51bGxfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKSB7CiAgICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpIHsKICAgICAgICBpZiAobnVsbF8gPT0gbnVsbCkgewogICAgICAgICAgbnVsbF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFudWxsXy5pc011dGFibGUoKSkgewogICAgICAgICAgbnVsbF8gPSBudWxsXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbnVsbF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdWxsQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0TnVsbCgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXROdWxsTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IG51bGxWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE51bGxWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TnVsbFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTnVsbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVOdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlTnVsbCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXROdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgbnVsbFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTnVsbCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZU51bGxWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TnVsbFZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxOdWxsVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTWFwQ29udGFpbmVyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9saXRlX3Rlc3QuTWFwQ29udGFpbmVyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE15TWFwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc015TWFwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TXlNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRNeU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRNeU1hcE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE15TWFwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm90b2NvbGJ1ZmZlcnMvcHJvdG9idWYvaXNzdWVzLzk3ODUKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9saXRlX3Rlc3QuTWFwQ29udGFpbmVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTWFwQ29udGFpbmVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9saXRlX3Rlc3QuTWFwQ29udGFpbmVyKQogICAgICBNYXBDb250YWluZXJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE1hcENvbnRhaW5lci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNYXBDb250YWluZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNYXBDb250YWluZXIoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTWFwQ29udGFpbmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfTWFwQ29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lci5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNWV9NQVBfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE15TWFwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfTXlNYXBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbXlNYXBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldE15TWFwKCkgewogICAgICBpZiAobXlNYXBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBteU1hcF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE15TWFwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc015TWFwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE15TWFwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TXlNYXAoKSB7CiAgICAgIHJldHVybiBnZXRNeU1hcE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNeU1hcE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TXlNYXBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNeU1hcCgpLAogICAgICAgICAgTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIG15TWFwX18gPSBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgbXlNYXBfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgb3RoZXIgPSAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0TXlNYXAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE15TWFwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTVlfTUFQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE15TWFwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm90b2NvbGJ1ZmZlcnMvcHJvdG9idWYvaXNzdWVzLzk3ODUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9saXRlX3Rlc3QuTWFwQ29udGFpbmVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2xpdGVfdGVzdC5NYXBDb250YWluZXIpCiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X01hcENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X01hcENvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIuY2xhc3MsIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIGJ1aWxkKCkgewogICAgICAgIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHJlc3VsdCA9IG5ldyBtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubXlNYXBfID0gaW50ZXJuYWxHZXRNeU1hcCgpOwogICAgICAgICAgcmVzdWx0Lm15TWFwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfbGl0ZV90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TXlNYXAoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIG15TWFwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbXlNYXBfXy5nZXRLZXkoKSwgbXlNYXBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBteU1hcF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNeU1hcCgpIHsKICAgICAgICBpZiAobXlNYXBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG15TWFwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkgewogICAgICAgIGlmIChteU1hcF8gPT0gbnVsbCkgewogICAgICAgICAgbXlNYXBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW15TWFwXy5pc011dGFibGUoKSkgewogICAgICAgICAgbXlNYXBfID0gbXlNYXBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBteU1hcF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNeU1hcENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc015TWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE15TWFwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNeU1hcCgpIHsKICAgICAgICByZXR1cm4gZ2V0TXlNYXBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TXlNYXBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TXlNYXBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNeU1hcCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNeU1hcCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTXlNYXAoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE15TWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTXlNYXAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2xpdGVfdGVzdC5NYXBDb250YWluZXIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF9saXRlX3Rlc3QuTWFwQ29udGFpbmVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX2xpdGVfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWFwQ29udGFpbmVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE1hcENvbnRhaW5lcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE1hcENvbnRhaW5lciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1hcENvbnRhaW5lcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNYXBDb250YWluZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF9saXRlX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9VaW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfVWludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQ2NFRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQ2NFRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25fZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JZkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX051bGxFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUHJpdmF0ZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ZvaWRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUGFja2FnZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfTnVsbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X01hcENvbnRhaW5lcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X01hcENvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfTXlNYXBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X01hcENvbnRhaW5lcl9NeU1hcEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG5cJ2NvbS9nb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdC5wcm90IiArCiAgICAgICJvXDAyMlxybWFwX2xpdGVfdGVzdFwiXDM0NFx0XG5cMDA3VGVzdE1hcFwwMjJLXG5cMDI0aW50MzJfdG8iICsKICAgICAgIl9pbnQzMl9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzItLm1hcF9saXRlX3Rlc3QuVGVzdE0iICsKICAgICAgImFwLkludDMyVG9JbnQzMkZpZWxkRW50cnlcMDIyTVxuXDAyNWludDMyX3RvX3N0IiArCiAgICAgICJyaW5nX2ZpZWxkXDAzMFwwMDIgXDAwMyhcMDEzMi4ubWFwX2xpdGVfdGVzdC5UZXN0TWFwIiArCiAgICAgICIuSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlcMDIyS1xuXDAyNGludDMyX3RvX2J5dCIgKwogICAgICAiZXNfZmllbGRcMDMwXDAwMyBcMDAzKFwwMTMyLS5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuSSIgKwogICAgICAibnQzMlRvQnl0ZXNGaWVsZEVudHJ5XDAyMklcblwwMjNpbnQzMl90b19lbnVtX2YiICsKICAgICAgImllbGRcMDMwXDAwNCBcMDAzKFwwMTMyLC5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuSW50MzIiICsKICAgICAgIlRvRW51bUZpZWxkRW50cnlcMDIyT1xuXDAyNmludDMyX3RvX21lc3NhZ2VfZmllIiArCiAgICAgICJsZFwwMzBcMDA1IFwwMDMoXDAxMzIvLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5JbnQzMlRvIiArCiAgICAgICJNZXNzYWdlRmllbGRFbnRyeVwwMjJNXG5cMDI1c3RyaW5nX3RvX2ludDMyX2ZpZSIgKwogICAgICAibGRcMDMwXDAwNiBcMDAzKFwwMTMyLi5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuU3RyaW5nVCIgKwogICAgICAib0ludDMyRmllbGRFbnRyeVwwMjJNXG5cMDI1dWludDMyX3RvX2ludDMyX2ZpZWwiICsKICAgICAgImRcMDMwXDAwNyBcMDAzKFwwMTMyLi5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuVWludDMyVG8iICsKICAgICAgIkludDMyRmllbGRFbnRyeVwwMjJLXG5cMDI0aW50NjRfdG9faW50MzJfZmllbGRcMDMwIiArCiAgICAgICJcMDEwIFwwMDMoXDAxMzItLm1hcF9saXRlX3Rlc3QuVGVzdE1hcC5JbnQ2NFRvSW50IiArCiAgICAgICIzMkZpZWxkRW50cnlcMDMyXDAzNVxuXDAxNE1lc3NhZ2VWYWx1ZVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMDVcMDMyOFxuXDAyNkludDMyVG9JbnQzMkZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEiICsKICAgICAgIihcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjlcblwwMjdJbnQzMlRvU3RyaW5nRmkiICsKICAgICAgImVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxIiArCiAgICAgICJcMDMyOFxuXDAyNkludDMyVG9CeXRlc0ZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMllcblwwMjVJbnQzMlRvRW51bUZpZWxkRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMi9cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIgLm1hcF9saSIgKwogICAgICAidGVfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZTpcMDAyOFwwMDFcMDMyX1xuXDAzMEludDMyVG8iICsKICAgICAgIk1lc3NhZ2VGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyMlxuXDAwNXZhbHVlXDAzMCIgKwogICAgICAiXDAwMiBcMDAxKFwwMTMyIy5tYXBfbGl0ZV90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbCIgKwogICAgICAidWU6XDAwMjhcMDAxXDAzMjlcblwwMjdTdHJpbmdUb0ludDMyRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjlcblwwMjdVaW50MzJUb0ludCIgKwogICAgICAiMzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDUiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyOFxuXDAyNkludDY0VG9JbnQzMkZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxICIgKwogICAgICAiXDAwMShcMDAzXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXCIvXG5cdEVudW1WYWx1ZVwwMjJcMDA3XG5cMDAzRiIgKwogICAgICAiT09cMDIwXDAwMFwwMjJcMDA3XG5cMDAzQkFSXDAyMFwwMDFcMDIyXDAwN1xuXDAwM0JBWlwwMjBcMDAyXDAyMlwwMDdcblwwMDNRVVhcMDIwXDAwM1wiUFxuXDAzNFRlc3RPIiArCiAgICAgICJuQ2hhbmdlRXZlbnRQcm9wYWdhdGlvblwwMjIwXG5cMDIwb3B0aW9uYWxfbWVzcyIgKwogICAgICAiYWdlXDAzMFwwMDEgXDAwMShcMDEzMlwwMjYubWFwX2xpdGVfdGVzdC5UZXN0TWFwXCJcMzU1XDAwNlxuXDAxNkJpIiArCiAgICAgICJ6YXJyb1Rlc3RNYXBcMDIyUlxuXDAyNGludDMyX3RvX2ludDMyX2ZpZWxkXDAzMFwwMDEgXDAwMyIgKwogICAgICAiKFwwMTMyNC5tYXBfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwLkludDMyVCIgKwogICAgICAib0ludDMyRmllbGRFbnRyeVwwMjJUXG5cMDI1aW50MzJfdG9fc3RyaW5nX2ZpZWwiICsKICAgICAgImRcMDMwXDAwMiBcMDAzKFwwMTMyNS5tYXBfbGl0ZV90ZXN0LkJpemFycm9UZXN0TWFwLkkiICsKICAgICAgIm50MzJUb1N0cmluZ0ZpZWxkRW50cnlcMDIyUlxuXDAyNGludDMyX3RvX2J5dGVzIiArCiAgICAgICJfZmllbGRcMDMwXDAwMyBcMDAzKFwwMTMyNC5tYXBfbGl0ZV90ZXN0LkJpemFycm9UZXN0IiArCiAgICAgICJNYXAuSW50MzJUb0J5dGVzRmllbGRFbnRyeVwwMjJQXG5cMDIzaW50MzJfdG9fZSIgKwogICAgICAibnVtX2ZpZWxkXDAzMFwwMDQgXDAwMyhcMDEzMjMubWFwX2xpdGVfdGVzdC5CaXphcnJvVCIgKwogICAgICAiZXN0TWFwLkludDMyVG9FbnVtRmllbGRFbnRyeVwwMjJWXG5cMDI2aW50MzJfdG8iICsKICAgICAgIl9tZXNzYWdlX2ZpZWxkXDAzMFwwMDUgXDAwMyhcMDEzMjYubWFwX2xpdGVfdGVzdC5CaXoiICsKICAgICAgImFycm9UZXN0TWFwLkludDMyVG9NZXNzYWdlRmllbGRFbnRyeVwwMjJUXG5cMDI1IiArCiAgICAgICJzdHJpbmdfdG9faW50MzJfZmllbGRcMDMwXDAwNiBcMDAzKFwwMTMyNS5tYXBfbGl0ZV90IiArCiAgICAgICJlc3QuQml6YXJyb1Rlc3RNYXAuU3RyaW5nVG9JbnQzMkZpZWxkRW50IiArCiAgICAgICJyeVwwMzI4XG5cMDI2SW50MzJUb0ludDMyRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyOVxuXDAyN0ludDMyVG9TdHJpbmdGaWUiICsKICAgICAgImxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI4XG5cMDI2SW50MzJUb0J5dGVzRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcciIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjdcblwwMjVJbnQzMlRvRW51bUZpZWxkRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI6XG5cMDMwSW4iICsKICAgICAgInQzMlRvTWVzc2FnZUZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI5XG5cMDI3U3RyaW5nVG9JbnQzMkZpZWxkRW50ciIgKwogICAgICAieVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwiXDI3MVwwMTBcblwwMjJSZSIgKwogICAgICAic2VydmVkQXNNYXBGaWVsZFwwMjI1XG5cMDAyaWZcMDMwXDAwMSBcMDAzKFwwMTMyKS5tYXBfbGl0ZV8iICsKICAgICAgInRlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkLklmRW50cnlcMDIyO1xuXDAwNWNvbnN0IiArCiAgICAgICJcMDMwXDAwMiBcMDAzKFwwMTMyLC5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsIiArCiAgICAgICJkLkNvbnN0RW50cnlcMDIyP1xuXDAwN3ByaXZhdGVcMDMwXDAwMyBcMDAzKFwwMTMyLi5tYXBfbGl0ZSIgKwogICAgICAiX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkLlByaXZhdGVFbnRyeVwwMjI7XG4iICsKICAgICAgIlwwMDVjbGFzc1wwMzBcMDA0IFwwMDMoXDAxMzIsLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc00iICsKICAgICAgImFwRmllbGQuQ2xhc3NFbnRyeVwwMjI3XG5cMDAzaW50XDAzMFwwMDUgXDAwMyhcMDEzMioubWFwX2xpIiArCiAgICAgICJ0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZC5JbnRFbnRyeVwwMjI5XG5cMDA0diIgKwogICAgICAib2lkXDAzMFwwMDYgXDAwMyhcMDEzMisubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRiIgKwogICAgICAiaWVsZC5Wb2lkRW50cnlcMDIyPVxuXDAwNnN0cmluZ1wwMzBcMDA3IFwwMDMoXDAxMzItLm1hcF9saXQiICsKICAgICAgImVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuU3RyaW5nRW50cnlcMDIyP1xuIiArCiAgICAgICJcMDA3cGFja2FnZVwwMzBcMDEwIFwwMDMoXDAxMzIuLm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBIiArCiAgICAgICJzTWFwRmllbGQuUGFja2FnZUVudHJ5XDAyMjlcblwwMDRlbnVtXDAzMFx0IFwwMDMoXDAxMzIrLm0iICsKICAgICAgImFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuRW51bUVudHIiICsKICAgICAgInlcMDIyOVxuXDAwNG51bGxcMDMwXG4gXDAwMyhcMDEzMisubWFwX2xpdGVfdGVzdC5SZXNlcnZlZCIgKwogICAgICAiQXNNYXBGaWVsZC5OdWxsRW50cnlcMDMyKVxuXDAwN0lmRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLFxuXG5Db25zdEVudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMi5cblwwMTRQcml2YXRlIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLFxuIiArCiAgICAgICJcbkNsYXNzRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6IiArCiAgICAgICJcMDAyOFwwMDFcMDMyKlxuXDAxMEludEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXHI6XDAwMjhcMDAxXDAzMitcblx0Vm9pZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMi1cblwwMTNTdHJpbmdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdCIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIuXG5cMDE0UGFja2FnZUVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMitcblx0RW51bUVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMitcblx0TnVsbCIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXCJcMjYyXDAxNiIgKwogICAgICAiXG5cMDM3UmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZVwwMjJCXG5cMDAyaWZcMDMwIiArCiAgICAgICJcMDAxIFwwMDMoXDAxMzI2Lm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkIiArCiAgICAgICJXaXRoRW51bVZhbHVlLklmRW50cnlcMDIySFxuXDAwNWNvbnN0XDAzMFwwMDIgXDAwMyhcMDEzMjkubSIgKwogICAgICAiYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtViIgKwogICAgICAiYWx1ZS5Db25zdEVudHJ5XDAyMkxcblwwMDdwcml2YXRlXDAzMFwwMDMgXDAwMyhcMDEzMjsubWFwX2wiICsKICAgICAgIml0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUiICsKICAgICAgIi5Qcml2YXRlRW50cnlcMDIySFxuXDAwNWNsYXNzXDAzMFwwMDQgXDAwMyhcMDEzMjkubWFwX2xpdGVfIiArCiAgICAgICJ0ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuQ2xhIiArCiAgICAgICJzc0VudHJ5XDAyMkRcblwwMDNpbnRcMDMwXDAwNSBcMDAzKFwwMTMyNy5tYXBfbGl0ZV90ZXN0LlJlcyIgKwogICAgICAiZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5JbnRFbnRyeVwwMjJGXG4iICsKICAgICAgIlwwMDR2b2lkXDAzMFwwMDYgXDAwMyhcMDEzMjgubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWEiICsKICAgICAgInBGaWVsZFdpdGhFbnVtVmFsdWUuVm9pZEVudHJ5XDAyMkpcblwwMDZzdHJpbmdcMDMwIiArCiAgICAgICJcMDA3IFwwMDMoXDAxMzI6Lm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkIiArCiAgICAgICJXaXRoRW51bVZhbHVlLlN0cmluZ0VudHJ5XDAyMkxcblwwMDdwYWNrYWdlXDAzMFwwMTAgXDAwMyIgKwogICAgICAiKFwwMTMyOy5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdCIgKwogICAgICAiaEVudW1WYWx1ZS5QYWNrYWdlRW50cnlcMDIyRlxuXDAwNGVudW1cMDMwXHQgXDAwMyhcMDEzMjguIiArCiAgICAgICJtYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtIiArCiAgICAgICJWYWx1ZS5FbnVtRW50cnlcMDIyRlxuXDAwNG51bGxcMDMwXG4gXDAwMyhcMDEzMjgubWFwX2xpdGUiICsKICAgICAgIl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuTnUiICsKICAgICAgImxsRW50cnlcMDMyZFxuXDAwN0lmRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIySFxuXDAwNXZhbHVlIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFwwMTYyOS5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXBGaWVsIiArCiAgICAgICJkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwwMzJnXG5cbkNvbnN0RW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJIXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyOS5tYXBfbGkiICsKICAgICAgInRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS4iICsKICAgICAgIlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmlcblwwMTRQcml2YXRlRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxICIgKwogICAgICAiXDAwMShcdFwwMjJIXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyOS5tYXBfbGl0ZV90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4IiArCiAgICAgICJcMDAxXDAzMmdcblxuQ2xhc3NFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJIXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAxNjI5Lm1hcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2kiICsKICAgICAgInRoRW51bVZhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmVcblwwMTBJbnRFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkhcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI5Lm1hcF9saXRlX3RlIiArCiAgICAgICJzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsIiArCiAgICAgICJlRW51bTpcMDAyOFwwMDFcMDMyZlxuXHRWb2lkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIySFxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyOS5tYXBfbGl0ZV90ZXN0LlJlc2VydmVkQXNNYXAiICsKICAgICAgIkZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwwMzJoXG5cMDEzU3RyIiArCiAgICAgICJpbmdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJIXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyOS5tIiArCiAgICAgICJhcF9saXRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WIiArCiAgICAgICJhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmlcblwwMTRQYWNrYWdlRW50cnlcMDIyXDAxM1xuXDAwM2siICsKICAgICAgImV5XDAzMFwwMDEgXDAwMShcdFwwMjJIXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyOS5tYXBfbGl0ZV90ZXN0LiIgKwogICAgICAiUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbiIgKwogICAgICAidW06XDAwMjhcMDAxXDAzMmZcblx0RW51bUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkhcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE2MjkubWFwX2xpdGVfdGVzdC5SZXNlcnZlZEFzTWFwRmllIiArCiAgICAgICJsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bTpcMDAyOFwwMDFcMDMyZlxuXHROdWxsRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJIXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyOS5tYXBfbGkiICsKICAgICAgInRlX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS4iICsKICAgICAgIlNhbXBsZUVudW06XDAwMjhcMDAxXCJcMDMyXG5cblNhbXBsZUVudW1cMDIyXDAwNVxuXDAwMUFcMDIwXDAwMFwwMjJcMDA1XG5cMDAxQiIgKwogICAgICAiXDAyMFwwMDFcInRcblwwMTRNYXBDb250YWluZXJcMDIyNlxuXDAwNm15X21hcFwwMzBcMDAxIFwwMDMoXDAxMzImLm1hcCIgKwogICAgICAiX2xpdGVfdGVzdC5NYXBDb250YWluZXIuTXlNYXBFbnRyeVwwMzIsXG5cbk15IiArCiAgICAgICJNYXBFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDEiICsKICAgICAgIkJcMDM3XG5ccm1hcF9saXRlX3Rlc3RCXDAxNE1hcFRlc3RQcm90b0hcMDAzYlwwMDZwcm90byIgKwogICAgICAiMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJJbnQzMlRvSW50MzJGaWVsZCIsICJJbnQzMlRvU3RyaW5nRmllbGQiLCAiSW50MzJUb0J5dGVzRmllbGQiLCAiSW50MzJUb0VudW1GaWVsZCIsICJJbnQzMlRvTWVzc2FnZUZpZWxkIiwgIlN0cmluZ1RvSW50MzJGaWVsZCIsICJVaW50MzJUb0ludDMyRmllbGQiLCAiSW50NjRUb0ludDMyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9VaW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9VaW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RNYXBfVWludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE1hcF9JbnQ2NFRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDY0VG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0TWFwX0ludDY0VG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Rlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25fZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbE1lc3NhZ2UiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW50MzJUb0ludDMyRmllbGQiLCAiSW50MzJUb1N0cmluZ0ZpZWxkIiwgIkludDMyVG9CeXRlc0ZpZWxkIiwgIkludDMyVG9FbnVtRmllbGQiLCAiSW50MzJUb01lc3NhZ2VGaWVsZCIsICJTdHJpbmdUb0ludDMyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSWYiLCAiQ29uc3QiLCAiUHJpdmF0ZSIsICJDbGFzc18iLCAiSW50IiwgIlZvaWQiLCAiU3RyaW5nIiwgIlBhY2thZ2UiLCAiRW51bSIsICJOdWxsIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JZkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfRW51bUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSWYiLCAiQ29uc3QiLCAiUHJpdmF0ZSIsICJDbGFzc18iLCAiSW50IiwgIlZvaWQiLCAiU3RyaW5nIiwgIlBhY2thZ2UiLCAiRW51bSIsICJOdWxsIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ZvaWRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk15TWFwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfTXlNYXBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9saXRlX3Rlc3RfTWFwQ29udGFpbmVyX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2xpdGVfdGVzdF9NYXBDb250YWluZXJfTXlNYXBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfbGl0ZV90ZXN0X01hcENvbnRhaW5lcl9NeU1hcEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAOitYAXBhQkAwYUJACMAAABtYXBfdGVzdC9NYXBGb3JQcm90bzJUZXN0UHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfZm9yX3Byb3RvMl90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBtYXBfdGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBNYXBGb3JQcm90bzJUZXN0UHJvdG8gewogIHByaXZhdGUgTWFwRm9yUHJvdG8yVGVzdFByb3RvKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGdldEludDMyVG9FbnVtRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBnZXRJbnQzMlRvRW51bUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4KICAgIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+CiAgICBnZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPgogICAgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBPclRocm93KAogICAgICAgIGludCBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcCkKICAgICAgVGVzdE1hcE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWFwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1hcCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5jbGFzcywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlfQogICAgICovCiAgICBwdWJsaWMgZW51bSBFbnVtVmFsdWUKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5RVVggPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIFFVWCgzKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlFVWCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUVVYX1ZBTFVFID0gMzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIEVudW1WYWx1ZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgRW51bVZhbHVlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBGT087CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBCQVI7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBCQVo7CiAgICAgICAgICBjYXNlIDM6IHJldHVybiBRVVg7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxFbnVtVmFsdWU+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBFbnVtVmFsdWU+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxFbnVtVmFsdWU+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBFbnVtVmFsdWUgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIEVudW1WYWx1ZS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVudW1WYWx1ZVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBFbnVtVmFsdWUgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlKQogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZVZhbHVlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNWYWx1ZSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBpbnQgZ2V0VmFsdWUoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNZXNzYWdlVmFsdWUgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgICAgTWVzc2FnZVZhbHVlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTWVzc2FnZVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTWVzc2FnZVZhbHVlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VWYWx1ZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuY2xhc3MsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCB2YWx1ZV8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCB2YWx1ZV8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBvdGhlciA9IChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIG9iajsKCiAgICAgICAgaWYgKGhhc1ZhbHVlKCkgIT0gb3RoZXIuaGFzVmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgICBpZiAoZ2V0VmFsdWUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldFZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRWYWx1ZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkKICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGJ1aWxkKCkgewogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHJlc3VsdCA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LnZhbHVlXyA9IHZhbHVlXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICAgIHNldFZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIHZhbHVlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgICB2YWx1ZV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlVmFsdWU+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlVmFsdWU+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTWVzc2FnZVZhbHVlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVZhbHVlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVZhbHVlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1ZhbHVlKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIGludCBnZXRWYWx1ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykKICAgICAgICBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgaWYgKCFoYXNWYWx1ZSgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBvdGhlciA9IChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKSBvYmo7CgogICAgICAgIGlmIChoYXNWYWx1ZSgpICE9IG90aGVyLmhhc1ZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgICAgaWYgKGdldFZhbHVlKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc30KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMpCiAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuY2xhc3MsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgYnVpbGQoKSB7CiAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHModGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1ZhbHVlKCkpIHsKICAgICAgICAgICAgc2V0VmFsdWUob3RoZXIuZ2V0VmFsdWUoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgaWYgKCFoYXNWYWx1ZSgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIHZhbHVlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgICB2YWx1ZV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX1NUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX0JZVEVTX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0VudW1GaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPiBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUsIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19NRVNTQUdFX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFVSVJFRF9NRVNTQUdFX01BUF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiByZXF1aXJlZE1lc3NhZ2VNYXBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPgogICAgaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKSB7CiAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VNYXBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBSZXF1aXJlZE1lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlTWFwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1JlcXVpcmVkTWVzc2FnZU1hcCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gZ2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICByZXR1cm4gZ2V0UmVxdWlyZWRNZXNzYWdlTWFwTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGdldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBmb3IgKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgaXRlbSA6IGdldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSwKICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLAogICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLAogICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCksCiAgICAgICAgICBSZXF1aXJlZE1lc3NhZ2VNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTEpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpbnQzMlRvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBpbnQzMlRvU3RyaW5nRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fID0gSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGludDMyVG9CeXRlc0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0VudW1GaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBzdHJpbmdUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4KICAgICAgICByZXF1aXJlZE1lc3NhZ2VNYXBfXyA9IFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEsIHJlcXVpcmVkTWVzc2FnZU1hcF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgb3RoZXIgPSAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9NRVNTQUdFX01BUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcCkKICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5jbGFzcywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIGJ1aWxkKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwIHJlc3VsdCA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9JbnQzMkZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9CeXRlc0ZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0VudW1GaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9NZXNzYWdlRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuYnVpbGQoSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcXVpcmVkTWVzc2FnZU1hcF8gPSBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmJ1aWxkKFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGZvciAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBpdGVtIDogZ2V0UmVxdWlyZWRNZXNzYWdlTWFwTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfXyA9IEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5mb3JOdW1iZXIoaW50MzJUb0VudW1GaWVsZF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoNCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9FbnVtRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgICAgICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fLmdldEtleSgpLCBzdHJpbmdUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+CiAgICAgICAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VNYXBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZU1hcF9fLmdldEtleSgpLCByZXF1aXJlZE1lc3NhZ2VNYXBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gaW50MzJUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvU3RyaW5nRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gaW50MzJUb1N0cmluZ0ZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0J5dGVzRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnQzMlRvQnl0ZXNGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9FbnVtRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9FbnVtRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkXyA9IGludDMyVG9FbnVtRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICAgIGdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgICBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnQzMlRvRW51bUZpZWxkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW50MzJUb0VudW1GaWVsZE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGJ1aWxkKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIHsgcmV0dXJuIChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyIGludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIgPSBuZXcgSW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXI+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9NZXNzYWdlRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihpbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9NZXNzYWdlRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldEludDMyVG9NZXNzYWdlRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlciBwdXRJbnQzMlRvTWVzc2FnZUZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgewogICAgICAgICAgZW50cnkgPSAoKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ1RvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBzdHJpbmdUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgYnVpbGQobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzKSB7IHJldHVybiAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcz4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIFJlcXVpcmVkTWVzc2FnZU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIgcmVxdWlyZWRNZXNzYWdlTWFwQ29udmVydGVyID0gbmV3IFJlcXVpcmVkTWVzc2FnZU1hcENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLkJ1aWxkZXI+IHJlcXVpcmVkTWVzc2FnZU1hcF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VNYXBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihyZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlTWFwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkTWVzc2FnZU1hcF8gPT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWRNZXNzYWdlTWFwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHJlcXVpcmVkTWVzc2FnZU1hcENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlTWFwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFJlcXVpcmVkTWVzc2FnZU1hcENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBnZXRSZXF1aXJlZE1lc3NhZ2VNYXAoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcXVpcmVkTWVzc2FnZU1hcE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVxdWlyZWRNZXNzYWdlTWFwKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZ2V0UmVxdWlyZWRNZXNzYWdlTWFwT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyByZXF1aXJlZE1lc3NhZ2VNYXBDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMmZ3Q7IHJlcXVpcmVkX21lc3NhZ2VfbWFwID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyBnZXRSZXF1aXJlZE1lc3NhZ2VNYXBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZU1hcENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlcXVpcmVkTWVzc2FnZU1hcCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+CiAgICAgICAgICBnZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcyZndDsgcmVxdWlyZWRfbWVzc2FnZV9tYXAgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxSZXF1aXJlZE1lc3NhZ2VNYXAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHM+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVxdWlyZWRNZXNzYWdlTWFwKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzJmd0OyByZXF1aXJlZF9tZXNzYWdlX21hcCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzLkJ1aWxkZXIgcHV0UmVxdWlyZWRNZXNzYWdlTWFwQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVSZXF1aXJlZE1lc3NhZ2VNYXAoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc09yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcy5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkcykgewogICAgICAgICAgZW50cnkgPSAoKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHMuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdE1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RVbmtub3duRW51bVZhbHVlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFVua25vd25FbnVtVmFsdWUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFVua25vd25FbnVtVmFsdWV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0VW5rbm93bkVudW1WYWx1ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RVbmtub3duRW51bVZhbHVlKQogICAgICBUZXN0VW5rbm93bkVudW1WYWx1ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFVua25vd25FbnVtVmFsdWUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFVua25vd25FbnVtVmFsdWUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VW5rbm93bkVudW1WYWx1ZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VW5rbm93bkVudW1WYWx1ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgb3RoZXIgPSAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RVbmtub3duRW51bVZhbHVlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0VW5rbm93bkVudW1WYWx1ZSkKICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZS5jbGFzcywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9JbnQzMkZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGludDMyVG9JbnQzMkZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBXaXJlLWNvbXBhdGlibGUgd2l0aCBUZXN0TWFwLmludDMyX3RvX2VudW1fZmllbGQgc28gd2UgY2FuIHRlc3QgdGhlCiAgICAgICAqIHBhcnNpbmcgYmVoYXZpb3Igb2YgVGVzdE1hcCByZWdhcmRpbmcgdW5rbm93biBlbnVtIHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFdpcmUtY29tcGF0aWJsZSB3aXRoIFRlc3RNYXAuaW50MzJfdG9fZW51bV9maWVsZCBzbyB3ZSBjYW4gdGVzdCB0aGUKICAgICAgICogcGFyc2luZyBiZWhhdmlvciBvZiBUZXN0TWFwIHJlZ2FyZGluZyB1bmtub3duIGVudW0gdmFsdWVzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2lyZS1jb21wYXRpYmxlIHdpdGggVGVzdE1hcC5pbnQzMl90b19lbnVtX2ZpZWxkIHNvIHdlIGNhbiB0ZXN0IHRoZQogICAgICAgKiBwYXJzaW5nIGJlaGF2aW9yIG9mIFRlc3RNYXAgcmVnYXJkaW5nIHVua25vd24gZW51bSB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RVbmtub3duRW51bVZhbHVlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RVbmtub3duRW51bVZhbHVlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0VW5rbm93bkVudW1WYWx1ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RVbmtub3duRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVua25vd25FbnVtVmFsdWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVua25vd25FbnVtVmFsdWU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VW5rbm93bkVudW1WYWx1ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbmtub3duRW51bVZhbHVlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbmtub3duRW51bVZhbHVlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFVua25vd25FbnVtVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UmVjdXJzaXZlTWFwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgKi8KICAgIGludCBnZXRWYWx1ZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZWN1cnNpdmVNYXBGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUmVjdXJzaXZlTWFwRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFJlY3Vyc2l2ZU1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+CiAgICBnZXRSZWN1cnNpdmVNYXBGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+CiAgICBnZXRSZWN1cnNpdmVNYXBGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgdGhhdCB0aGUgbWFwcyBpbml0aWFsaXphdGlvbiBjb2RlIHdvcmtzIGNvcnJlY3RseSB3aGVuIHRoZSBtYXAgZmllbGQKICAgKiByZWZlcmVuY2VzIHRoZSBjb250YWluaW5nIG1lc3NhZ2UuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVjdXJzaXZlTWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCkKICAgICAgVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFJlY3Vyc2l2ZU1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UmVjdXJzaXZlTWFwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlY3Vyc2l2ZU1hcCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UmVjdXJzaXZlTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuY2xhc3MsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgdmFsdWVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgIHJldHVybiB2YWx1ZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVDVVJTSVZFX01BUF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9SZWN1cnNpdmVNYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gcmVjdXJzaXZlTWFwRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4KICAgIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKSB7CiAgICAgIGlmIChyZWN1cnNpdmVNYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFJlY3Vyc2l2ZU1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlY3Vyc2l2ZU1hcEZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0UmVjdXJzaXZlTWFwRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1JlY3Vyc2l2ZU1hcEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+IGdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgdmFsdWVfKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFJlY3Vyc2l2ZU1hcEZpZWxkKCksCiAgICAgICAgICBSZWN1cnNpdmVNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgdmFsdWVfKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4KICAgICAgICByZWN1cnNpdmVNYXBGaWVsZF9fID0gUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIHJlY3Vyc2l2ZU1hcEZpZWxkX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBvdGhlciA9IChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCkgb2JqOwoKICAgICAgaWYgKGhhc1ZhbHVlKCkgIT0gb3RoZXIuaGFzVmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgIGlmIChnZXRWYWx1ZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRUNVUlNJVkVfTUFQX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IHRoZSBtYXBzIGluaXRpYWxpemF0aW9uIGNvZGUgd29ya3MgY29ycmVjdGx5IHdoZW4gdGhlIG1hcCBmaWVsZAogICAgICogcmVmZXJlbmNlcyB0aGUgY29udGFpbmluZyBtZXNzYWdlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwKQogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuY2xhc3MsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnZhbHVlXyA9IHZhbHVlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZWN1cnNpdmVNYXBGaWVsZF8gPSBpbnRlcm5hbEdldFJlY3Vyc2l2ZU1hcEZpZWxkKCkuYnVpbGQoUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc1ZhbHVlKCkpIHsKICAgICAgICAgIHNldFZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICB2YWx1ZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+CiAgICAgICAgICAgICAgICByZWN1cnNpdmVNYXBGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUmVjdXJzaXZlTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZU1hcEZpZWxkX18uZ2V0S2V5KCksIHJlY3Vyc2l2ZU1hcEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgdmFsdWVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgdmFsdWVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBSZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBidWlsZChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCkgeyByZXR1cm4gKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBSZWN1cnNpdmVNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlciByZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlciA9IG5ldyBSZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLkJ1aWxkZXI+IHJlY3Vyc2l2ZU1hcEZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpIHsKICAgICAgICBpZiAocmVjdXJzaXZlTWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihyZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZWN1cnNpdmVNYXBGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZU1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZWN1cnNpdmVNYXBGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihyZWN1cnNpdmVNYXBGaWVsZENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcmVjdXJzaXZlTWFwRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVjdXJzaXZlTWFwRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1JlY3Vyc2l2ZU1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRSZWN1cnNpdmVNYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPiBnZXRSZWN1cnNpdmVNYXBGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcD4gZ2V0UmVjdXJzaXZlTWFwRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UmVjdXJzaXZlTWFwRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBnZXRSZWN1cnNpdmVNYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IHJlY3Vyc2l2ZU1hcEZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0UmVjdXJzaXZlTWFwRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlY3Vyc2l2ZU1hcEZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZWN1cnNpdmVNYXBGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlY3Vyc2l2ZU1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVSZWN1cnNpdmVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwPgogICAgICAgICAgZ2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFJlY3Vyc2l2ZU1hcCZndDsgcmVjdXJzaXZlX21hcF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UmVjdXJzaXZlTWFwRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXAmZ3Q7IHJlY3Vyc2l2ZV9tYXBfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFJlY3Vyc2l2ZU1hcEZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXA+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUmVjdXJzaXZlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwJmd0OyByZWN1cnNpdmVfbWFwX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuQnVpbGRlciBwdXRSZWN1cnNpdmVNYXBGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcE9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZVJlY3Vyc2l2ZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcC5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXApIHsKICAgICAgICAgIGVudHJ5ID0gKChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0UmVjdXJzaXZlTWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlTWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZWN1cnNpdmVNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVjdXJzaXZlTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlY3Vyc2l2ZU1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlTWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEJpemFycm9UZXN0TWFwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuQml6YXJyb1Rlc3RNYXApCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9NZXNzYWdlRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIGEgZGVjb3kgb2YgVGVzdE1hcCBmb3IgdGVzdGluZyBwYXJzaW5nIGVycm9ycwogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5CaXphcnJvVGVzdE1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJpemFycm9UZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF9mb3JfcHJvdG8yX3Rlc3QuQml6YXJyb1Rlc3RNYXApCiAgICAgIEJpemFycm9UZXN0TWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBCaXphcnJvVGVzdE1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBCaXphcnJvVGVzdE1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEJpemFycm9UZXN0TWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEJpemFycm9UZXN0TWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX0VOVU1fRklFTERfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9FbnVtRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgaWYgKGludDMyVG9FbnVtRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9FbnVtRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CWVRFUywKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb01lc3NhZ2VGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICBpZiAoc3RyaW5nVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLAogICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSwKICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSwKICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaW50MzJUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfXyA9IEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgaW50MzJUb1N0cmluZ0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fID0gSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGludDMyVG9CeXRlc0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0VudW1GaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXyA9IEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGludDMyVG9NZXNzYWdlRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBzdHJpbmdUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgb3RoZXIgPSAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogYSBkZWNveSBvZiBUZXN0TWFwIGZvciB0ZXN0aW5nIHBhcnNpbmcgZXJyb3JzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfZm9yX3Byb3RvMl90ZXN0LkJpemFycm9UZXN0TWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5CaXphcnJvVGVzdE1hcCkKICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXBPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGJ1aWxkKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHJlc3VsdCA9IG5ldyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0ludDMyRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9JbnQzMkZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50MzJUb1N0cmluZ0ZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb1N0cmluZ0ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0J5dGVzRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9CeXRlc0ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0VudW1GaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvRW51bUZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50MzJUb01lc3NhZ2VGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvTWVzc2FnZUZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nVG9JbnQzMkZpZWxkXyA9IGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuc3RyaW5nVG9JbnQzMkZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0J5dGVzRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9FbnVtRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgc3RyaW5nVG9JbnQzMkZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkXyA9IGludDMyVG9JbnQzMkZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvU3RyaW5nRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gaW50MzJUb1N0cmluZ0ZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0J5dGVzRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnQzMlRvQnl0ZXNGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0VudW1GaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvRW51bUZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0VudW1GaWVsZF8gPSBpbnQzMlRvRW51bUZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9NZXNzYWdlRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGludDMyVG9NZXNzYWdlRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghc3RyaW5nVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgc3RyaW5nVG9JbnQzMkZpZWxkXyA9IHN0cmluZ1RvSW50MzJGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5CaXphcnJvVGVzdE1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qml6YXJyb1Rlc3RNYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Qml6YXJyb1Rlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCaXphcnJvVGVzdE1hcCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJpemFycm9UZXN0TWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJpemFycm9UZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBSZXNlcnZlZEFzTWFwRmllbGRPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJZkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SWZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWZNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDb25zdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q29uc3RNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q29uc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q29uc3RNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENvbnN0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFByaXZhdGVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQcml2YXRlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENsYXNzX01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Vm9pZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFBhY2thZ2VNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFBhY2thZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEVudW1NYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE51bGxDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXROdWxsKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFVzZWQgdG8gdGVzdCB0aGF0IGphdmEgcmVzZXJ2ZWQgd29yZHMgY2FuIGJlIHVzZWQgYXMgcHJvdG9idWYgZmllbGQgbmFtZXMKICAgKiBOb3QgYWxsIHJlc2VydmVkIHdvcmRzIGFyZSB0ZXN0ZWQgKHRvIGF2b2lkIGJsb2F0KSBidXQgaW5zdGVhZCBhbiBhcmJpdHJhcnkKICAgKiBzdWJzZXQgb2YgdGhlbSBjaG9zZW4gdG8gY292ZXIgdmFyaW91cyBrZXl3b3JkIGNhdGVnb3JpZXMgbGlrZQogICAqIHR5cGUsIG1vZGlmaWVyLCBkZWNsYXJhdGlvbiwgZXRjLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXNlcnZlZEFzTWFwRmllbGQgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQpCiAgICAgIFJlc2VydmVkQXNNYXBGaWVsZE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUmVzZXJ2ZWRBc01hcEZpZWxkLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFJlc2VydmVkQXNNYXBGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFJlc2VydmVkQXNNYXBGaWVsZCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSZXNlcnZlZEFzTWFwRmllbGQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgIGNhc2UgODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJZkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgIGlmIChpZl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGlmXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJZigpIHsKICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SWZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTlNUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDb25zdERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgIGlmIChjb25zdF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbnN0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDb25zdCgpIHsKICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSVZBVEVfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Qcml2YXRlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHByaXZhdGVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQcml2YXRlKCkgewogICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZSgpIHsKICAgICAgcmV0dXJuIGdldFByaXZhdGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQcml2YXRlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NsYXNzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldENsYXNzXygpIHsKICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBjbGFzc19fOwogICAgfQogICAgcHVibGljIGludCBnZXRDbGFzc19Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q2xhc3NfKCkgewogICAgICByZXR1cm4gZ2V0Q2xhc3NfTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENsYXNzX01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludCgpIHsKICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludCgpIHsKICAgICAgcmV0dXJuIGdldEludE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWT0lEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2b2lkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Vm9pZCgpIHsKICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZvaWRfOwogICAgfQogICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFZvaWQoKSB7CiAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Vm9pZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRWb2lkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRWb2lkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFN0cmluZygpIHsKICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdfOwogICAgfQogICAgcHVibGljIGludCBnZXRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tBR0VfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHBhY2thZ2VfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcGFja2FnZV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2FnZSgpIHsKICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQYWNrYWdlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRW51bURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEVudW0oKSB7CiAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtKCkgewogICAgICByZXR1cm4gZ2V0RW51bU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEVudW1NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RW51bU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RW51bU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTnVsbERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX051bGxFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE51bGwoKSB7CiAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBudWxsXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TnVsbENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TnVsbCgpIHsKICAgICAgcmV0dXJuIGdldE51bGxNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TnVsbE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE51bGxPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SWYoKSwKICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSwKICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLAogICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLAogICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50KCksCiAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCksCiAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCksCiAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCksCiAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLAogICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKSwKICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTApOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGlmX18gPSBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaWZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNvbnN0X18gPSBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgY29uc3RfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgcHJpdmF0ZV9fID0gUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgcHJpdmF0ZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNsYXNzX19fID0gQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBjbGFzc19fXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnRfXyA9IEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHZvaWRfXyA9IFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHZvaWRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBzdHJpbmdfXyA9IFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNywgc3RyaW5nX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHBhY2thZ2VfXyA9IFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIHBhY2thZ2VfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZW51bV9fID0gRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZW51bV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBudWxsX18gPSBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgbnVsbF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIG90aGVyID0gKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SWYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldENvbnN0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDb25zdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UHJpdmF0ZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Q2xhc3NfKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDbGFzc18oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRWb2lkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UGFja2FnZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UGFja2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TnVsbCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TnVsbCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElGX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldElmKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDT05TVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDb25zdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUklWQVRFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFByaXZhdGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDbGFzc18oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZPSURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Vm9pZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRQYWNrYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RW51bSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOVUxMX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE51bGwoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFVzZWQgdG8gdGVzdCB0aGF0IGphdmEgcmVzZXJ2ZWQgd29yZHMgY2FuIGJlIHVzZWQgYXMgcHJvdG9idWYgZmllbGQgbmFtZXMKICAgICAqIE5vdCBhbGwgcmVzZXJ2ZWQgd29yZHMgYXJlIHRlc3RlZCAodG8gYXZvaWQgYmxvYXQpIGJ1dCBpbnN0ZWFkIGFuIGFyYml0cmFyeQogICAgICogc3Vic2V0IG9mIHRoZW0gY2hvc2VuIHRvIGNvdmVyIHZhcmlvdXMga2V5d29yZCBjYXRlZ29yaWVzIGxpa2UKICAgICAqIHR5cGUsIG1vZGlmaWVyLCBkZWNsYXJhdGlvbiwgZXRjLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbnVtKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlmXyA9IGludGVybmFsR2V0SWYoKTsKICAgICAgICAgIHJlc3VsdC5pZl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvbnN0XyA9IGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICAgIHJlc3VsdC5jb25zdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByaXZhdGVfID0gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNsYXNzX18gPSBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgcmVzdWx0LmNsYXNzX18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludF8gPSBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgcmVzdWx0LmludF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnZvaWRfID0gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICByZXN1bHQudm9pZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ18gPSBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBhY2thZ2VfID0gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmVudW1fID0gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICByZXN1bHQuZW51bV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm51bGxfID0gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICByZXN1bHQubnVsbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaWZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpZl9fLmdldEtleSgpLCBpZl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNvbnN0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY29uc3RfXy5nZXRLZXkoKSwgY29uc3RfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBwcml2YXRlX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHByaXZhdGVfXy5nZXRLZXkoKSwgcHJpdmF0ZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNsYXNzX19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY2xhc3NfX18uZ2V0S2V5KCksIGNsYXNzX19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50X18uZ2V0S2V5KCksIGludF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHZvaWRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgdm9pZF9fLmdldEtleSgpLCB2b2lkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgc3RyaW5nX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBzdHJpbmdfXy5nZXRLZXkoKSwgc3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcGFja2FnZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBwYWNrYWdlX18uZ2V0S2V5KCksIHBhY2thZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBlbnVtX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGVudW1fXy5nZXRLZXkoKSwgZW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG51bGxfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbnVsbF9fLmdldEtleSgpLCBudWxsX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIGlmXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpZl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGlmXyA9IGlmXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaWZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SWYoKSB7CiAgICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJZk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJZk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySWYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUlmKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dElmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbElmKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjb25zdF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbnN0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY29uc3RfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q29uc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29uc3QoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dENvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENvbnN0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHByaXZhdGVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKSB7CiAgICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpIHsKICAgICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgICAgcHJpdmF0ZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcml2YXRlXy5pc011dGFibGUoKSkgewogICAgICAgICAgcHJpdmF0ZV8gPSBwcml2YXRlXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQcml2YXRlKCkgewogICAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJpdmF0ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVQcml2YXRlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQcml2YXRlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY2xhc3NfXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKSB7CiAgICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzX187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIGNsYXNzX18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWNsYXNzX18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNsYXNzX18gPSBjbGFzc19fLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDbGFzc18oKSB7CiAgICAgICAgcmV0dXJuIGdldENsYXNzX01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDbGFzc19NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlQ2xhc3NfKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENsYXNzXygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKSB7CiAgICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkgewogICAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICAgIGludF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludF8gPSBpbnRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50KCkgewogICAgICAgIHJldHVybiBnZXRJbnRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZvaWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKSB7CiAgICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdm9pZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpIHsKICAgICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgICAgdm9pZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF2b2lkXy5pc011dGFibGUoKSkgewogICAgICAgICAgdm9pZF8gPSB2b2lkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdm9pZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRWb2lkKCkgewogICAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Vm9pZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZvaWRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVm9pZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVWb2lkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxWb2lkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKSB7CiAgICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ18gPSBzdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICAgIHBhY2thZ2VfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcGFja2FnZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHBhY2thZ2VfID0gcGFja2FnZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2FnZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UGFja2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFBhY2thZ2VNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlUGFja2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsUGFja2FnZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudW1fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKSB7CiAgICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW51bV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgICAgZW51bV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlbnVtXy5pc011dGFibGUoKSkgewogICAgICAgICAgZW51bV8gPSBlbnVtXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZW51bV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEVudW0oKSB7CiAgICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEVudW1NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBudWxsXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkgewogICAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGxfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICAgIG51bGxfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbnVsbF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG51bGxfID0gbnVsbF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG51bGxfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TnVsbCgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldE51bGxNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bGwoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTnVsbCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTnVsbCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGQ+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SWYoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJZk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q29uc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNQcml2YXRlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFByaXZhdGUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFByaXZhdGVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q2xhc3NfQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q2xhc3NfTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEludE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1N0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFBhY2thZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0VudW0oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0RW51bSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0RW51bU1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0TnVsbE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpCiAgICAgIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgIGNhc2UgODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuY2xhc3MsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFNhbXBsZUVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBBKDApLAogICAgICAvKioKICAgICAgICogPGNvZGU+QiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQigxKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkEgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+QiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQl9WQUxVRSA9IDE7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBTYW1wbGVFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBTYW1wbGVFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBBOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gQjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFNhbXBsZUVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBTYW1wbGVFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8U2FtcGxlRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFNhbXBsZUVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFNhbXBsZUVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTYW1wbGVFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFNhbXBsZUVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBTYW1wbGVFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6bWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0pCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUZfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElmRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgIGlmIChpZl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGlmXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBpZlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRJZk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBpZlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJZigpIHsKICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldElmTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09OU1RfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q29uc3QoKSB7CiAgICAgIGlmIChjb25zdF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbnN0XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBjb25zdFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBjb25zdFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDb25zdCgpIHsKICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENvbnN0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGNvbnN0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENvbnN0T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbnN0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJVkFURV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHByaXZhdGVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQcml2YXRlKCkgewogICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gcHJpdmF0ZVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHByaXZhdGVWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UHJpdmF0ZSgpIHsKICAgICAgcmV0dXJuIGdldFByaXZhdGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQcml2YXRlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByaXZhdGVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldENsYXNzXygpIHsKICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBjbGFzc19fOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGNsYXNzX1ZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgY2xhc3NfVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRDbGFzc19Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q2xhc3NfKCkgewogICAgICByZXR1cm4gZ2V0Q2xhc3NfTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzX01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gY2xhc3NfVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gY2xhc3NfVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSW50RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludCgpIHsKICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGludFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgaW50VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEludCgpIHsKICAgICAgcmV0dXJuIGdldEludE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SW50TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gaW50VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZPSURfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFZvaWREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2b2lkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Vm9pZCgpIHsKICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZvaWRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZvaWRWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB2b2lkVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFZvaWQoKSB7CiAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Vm9pZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdm9pZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFN0cmluZygpIHsKICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHN0cmluZ1ZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgc3RyaW5nVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0U3RyaW5nKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gc3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0FHRV9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHBhY2thZ2VfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcGFja2FnZV87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gcGFja2FnZVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQSk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRQYWNrYWdlTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHBhY2thZ2VWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFBhY2thZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZSgpIHsKICAgICAgcmV0dXJuIGdldFBhY2thZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQYWNrYWdlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEVudW0oKSB7CiAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBlbnVtVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgZW51bVZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRFbnVtKCkgewogICAgICByZXR1cm4gZ2V0RW51bU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEVudW1NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRFbnVtTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTExfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE51bGwoKSB7CiAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBudWxsXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBudWxsVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgbnVsbFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TnVsbENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0TnVsbCgpIHsKICAgICAgcmV0dXJuIGdldE51bGxNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0TnVsbE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IG51bGxWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG51bGxWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLAogICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLAogICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCksCiAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCksCiAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKSwKICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKSwKICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKSwKICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSwKICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCksCiAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLAogICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaWZfXyA9IElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpZl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgY29uc3RfXyA9IENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBjb25zdF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBwcml2YXRlX18gPSBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBwcml2YXRlX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgY2xhc3NfX18gPSBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGNsYXNzX19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGludF9fID0gSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBpbnRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdm9pZF9fID0gVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgdm9pZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHN0cmluZ19fID0gU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCBzdHJpbmdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgcGFja2FnZV9fID0gUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgcGFja2FnZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBlbnVtX18gPSBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBlbnVtX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIG51bGxfXyA9IE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCBudWxsX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBvdGhlciA9IChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldElmKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Q29uc3QoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENvbnN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRQcml2YXRlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRQcml2YXRlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRDbGFzc18oKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0SW50KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFZvaWQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFZvaWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRQYWNrYWdlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRQYWNrYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRFbnVtKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRFbnVtKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXROdWxsKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSUZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SWYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENPTlNUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldENvbnN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBSSVZBVEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0UHJpdmF0ZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENMQVNTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldENsYXNzXygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVk9JRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRWb2lkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFBhY2thZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRFbnVtKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5VTExfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TnVsbCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUlmKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU51bGwoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmNsYXNzLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaWZfID0gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgcmVzdWx0LmlmXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY29uc3RfID0gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgcmVzdWx0LmNvbnN0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8gPSBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIHJlc3VsdC5wcml2YXRlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXyA9IGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50XyA9IGludGVybmFsR2V0SW50KCk7CiAgICAgICAgICByZXN1bHQuaW50Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudm9pZF8gPSBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICAgIHJlc3VsdC52b2lkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXyA9IGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8gPSBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrYWdlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZW51bV8gPSBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIHJlc3VsdC5lbnVtXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubnVsbF8gPSBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIHJlc3VsdC5udWxsXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpZl9fID0gSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uZm9yTnVtYmVyKGlmX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBpZl9fLmdldEtleSgpLCBpZl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjb25zdF9fID0gQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uZm9yTnVtYmVyKGNvbnN0X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBjb25zdF9fLmdldEtleSgpLCBjb25zdF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBwcml2YXRlX18gPSBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihwcml2YXRlX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgzLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGVfXy5nZXRLZXkoKSwgcHJpdmF0ZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBjbGFzc19fXyA9IENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5mb3JOdW1iZXIoY2xhc3NfX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg0LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgY2xhc3NfX18uZ2V0S2V5KCksIGNsYXNzX19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnRfXyA9IEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5mb3JOdW1iZXIoaW50X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg1LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgaW50X18uZ2V0S2V5KCksIGludF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB2b2lkX18gPSBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcih2b2lkX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg2LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHZvaWRfXy5nZXRLZXkoKSwgdm9pZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBzdHJpbmdfXyA9IFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAobWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5mb3JOdW1iZXIoc3RyaW5nX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg3LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nX18uZ2V0S2V5KCksIHN0cmluZ19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBwYWNrYWdlX18gPSBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihwYWNrYWdlX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg4LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VfXy5nZXRLZXkoKSwgcGFja2FnZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBlbnVtX18gPSBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihlbnVtX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCg5LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGVudW1fXy5nZXRLZXkoKSwgZW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBudWxsX18gPSBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmZvck51bWJlcihudWxsX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxMCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICBudWxsX18uZ2V0S2V5KCksIG51bGxfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpZl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SWYoKSB7CiAgICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpZl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKSB7CiAgICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgICBpZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaWZfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpZl8gPSBpZl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldElmQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SWYoKSB7CiAgICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SWZNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJZigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUlmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVJZigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgaWZWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJZigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjb25zdF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbnN0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY29uc3RfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDb25zdCgpIHsKICAgICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDb25zdE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dENvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBjb25zdFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENvbnN0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcHJpdmF0ZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpIHsKICAgICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwcml2YXRlXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkgewogICAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgICBwcml2YXRlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXByaXZhdGVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBwcml2YXRlXyA9IHByaXZhdGVfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBwcml2YXRlXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UHJpdmF0ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UHJpdmF0ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UHJpdmF0ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHByaXZhdGVWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFByaXZhdGVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcHJpdmF0ZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJpdmF0ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVByaXZhdGUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQcml2YXRlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgICBjbGFzc19fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjbGFzc19fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjbGFzc19fID0gY2xhc3NfXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY2xhc3NfXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRDbGFzc18oKSB7CiAgICAgICAgcmV0dXJuIGdldENsYXNzX01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldENsYXNzX01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ2xhc3NfTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2xhc3NfKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUNsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dENsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENsYXNzXygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkQ2xhc3NfTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKSB7CiAgICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkgewogICAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICAgIGludF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludF8gPSBpbnRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRJbnQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRJbnRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gaW50VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJbnRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgaW50VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdm9pZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpIHsKICAgICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2b2lkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkgewogICAgICAgIGlmICh2b2lkXyA9PSBudWxsKSB7CiAgICAgICAgICB2b2lkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXZvaWRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB2b2lkXyA9IHZvaWRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB2b2lkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFZvaWRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Vm9pZCgpIHsKICAgICAgICByZXR1cm4gZ2V0Vm9pZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Vm9pZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRWb2lkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHZvaWRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdm9pZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVm9pZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVZvaWQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRWb2lkTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0Vm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxWb2lkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRWb2lkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdfID0gc3RyaW5nXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gc3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFN0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRTdHJpbmdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICAgIHBhY2thZ2VfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcGFja2FnZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHBhY2thZ2VfID0gcGFja2FnZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRQYWNrYWdlKCkgewogICAgICAgIHJldHVybiBnZXRQYWNrYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRQYWNrYWdlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRQYWNrYWdlTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gcGFja2FnZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVBhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlUGFja2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFBhY2thZ2VNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQYWNrYWdlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFBhY2thZ2UoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFBhY2thZ2VNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RW51bSgpIHsKICAgICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbnVtXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkgewogICAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnVtXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVudW1fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBlbnVtXyA9IGVudW1fLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBlbnVtXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRFbnVtKCkgewogICAgICAgIHJldHVybiBnZXRFbnVtTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldEVudW1NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0RW51bU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkRW51bU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0RW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbnVsbF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpIHsKICAgICAgICBpZiAobnVsbF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkgewogICAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgICBudWxsXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW51bGxfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBudWxsXyA9IG51bGxfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBudWxsXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bGxDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0TnVsbCgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0TnVsbE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkTnVsbE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IG51bGxWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTnVsbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVOdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwRm9yUHJvdG8yVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBudWxsVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxOdWxsKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBGb3JQcm90bzJUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcEZvclByb3RvMlRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfUmVxdWlyZWRNZXNzYWdlTWFwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfSW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX1JlY3Vyc2l2ZU1hcEZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX1JlY3Vyc2l2ZU1hcEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Qcml2YXRlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NsYXNzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Wb2lkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9TdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUGFja2FnZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfRW51bUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX051bGxFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Db25zdEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Db25zdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSW50RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfVm9pZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfTnVsbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi1jb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9mb3JfcHJvdG8yX3RlcyIgKwogICAgICAidC5wcm90b1wwMjJcMDIzbWFwX2Zvcl9wcm90bzJfdGVzdFwiXDM2Nlx0XG5cMDA3VGVzdE1hcCIgKwogICAgICAiXDAyMlFcblwwMjRpbnQzMl90b19pbnQzMl9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzIzLm1hcF9mb3IiICsKICAgICAgIl9wcm90bzJfdGVzdC5UZXN0TWFwLkludDMyVG9JbnQzMkZpZWxkRW4iICsKICAgICAgInRyeVwwMjJTXG5cMDI1aW50MzJfdG9fc3RyaW5nX2ZpZWxkXDAzMFwwMDIgXDAwMyhcMDEzMjQubWFwIiArCiAgICAgICJfZm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuSW50MzJUb1N0cmluZ0ZpIiArCiAgICAgICJlbGRFbnRyeVwwMjJRXG5cMDI0aW50MzJfdG9fYnl0ZXNfZmllbGRcMDMwXDAwMyBcMDAzKFwwMTMyMyIgKwogICAgICAiLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5JbnQzMlRvQnl0ZSIgKwogICAgICAic0ZpZWxkRW50cnlcMDIyT1xuXDAyM2ludDMyX3RvX2VudW1fZmllbGRcMDMwXDAwNCBcMDAzKFwwMTMiICsKICAgICAgIjIyLm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcC5JbnQzMlRvRW4iICsKICAgICAgInVtRmllbGRFbnRyeVwwMjJVXG5cMDI2aW50MzJfdG9fbWVzc2FnZV9maWVsZFwwMzBcMDA1IiArCiAgICAgICIgXDAwMyhcMDEzMjUubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkludDMyIiArCiAgICAgICJUb01lc3NhZ2VGaWVsZEVudHJ5XDAyMlNcblwwMjVzdHJpbmdfdG9faW50MzJfZiIgKwogICAgICAiaWVsZFwwMzBcMDA2IFwwMDMoXDAxMzI0Lm1hcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdE1hcCIgKwogICAgICAiLlN0cmluZ1RvSW50MzJGaWVsZEVudHJ5XDAyMlJcblwwMjRyZXF1aXJlZF9tZXMiICsKICAgICAgInNhZ2VfbWFwXDAzMFwwMTMgXDAwMyhcMDEzMjQubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXMiICsKICAgICAgInRNYXAuUmVxdWlyZWRNZXNzYWdlTWFwRW50cnlcMDMyXDAzNVxuXDAxNE1lc3NhZ2VWIiArCiAgICAgICJhbHVlXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAxKFwwMDVcMDMyOFxuXDAyNkludDMyVG9JbnQzMkZpZWxkIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjlcbiIgKwogICAgICAiXDAyN0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcdDpcMDAyOFwwMDFcMDMyOFxuXDAyNkludDMyVG9CeXRlc0ZpZWxkRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMl9cblwwMjVJbiIgKwogICAgICAidDMyVG9FbnVtRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjVcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE2MiYubWFwX2Zvcl9wcm90bzJfdGVzdC5UZXN0TWFwLkVuIiArCiAgICAgICJ1bVZhbHVlOlwwMDI4XDAwMVwwMzJlXG5cMDMwSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyKS5tYXBfZm9yX3ByIiArCiAgICAgICJvdG8yX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWU6XDAwMjhcMDAxXDAzMjlcblwwMjdTdCIgKwogICAgICAicmluZ1RvSW50MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmEiICsKICAgICAgImx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyKlxuXDAzMU1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsIiArCiAgICAgICJkc1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDEgXDAwMihcMDA1XDAzMnFcblwwMjdSZXF1aXJlZE1lc3NhZ2VNYXBFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyRVxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMjYubWFwX2YiICsKICAgICAgIm9yX3Byb3RvMl90ZXN0LlRlc3RNYXAuTWVzc2FnZVdpdGhSZXF1aXIiICsKICAgICAgImVkRmllbGRzOlwwMDI4XDAwMVwiL1xuXHRFbnVtVmFsdWVcMDIyXDAwN1xuXDAwM0ZPT1wwMjBcMDAwXDAyMlwwMDdcblwwMDNCQSIgKwogICAgICAiUlwwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVpcMDIwXDAwMlwwMjJcMDA3XG5cMDAzUVVYXDAyMFwwMDNcIlwyNjBcMDAxXG5cMDI0VGVzdFVua25vd25FbnUiICsKICAgICAgIm1WYWx1ZVwwMjJeXG5cMDI0aW50MzJfdG9faW50MzJfZmllbGRcMDMwXDAwNCBcMDAzKFwwMTMyQC5tIiArCiAgICAgICJhcF9mb3JfcHJvdG8yX3Rlc3QuVGVzdFVua25vd25FbnVtVmFsdWUuIiArCiAgICAgICJJbnQzMlRvSW50MzJGaWVsZEVudHJ5XDAzMjhcblwwMjZJbnQzMlRvSW50MzJGaSIgKwogICAgICAiZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMSIgKwogICAgICAiXCJcMzM1XDAwMVxuXDAyMFRlc3RSZWN1cnNpdmVNYXBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJZXG5cMDIzIiArCiAgICAgICJyZWN1cnNpdmVfbWFwX2ZpZWxkXDAzMFwwMDIgXDAwMyhcMDEzMjwubWFwX2Zvcl9wcm90IiArCiAgICAgICJvMl90ZXN0LlRlc3RSZWN1cnNpdmVNYXAuUmVjdXJzaXZlTWFwRmllIiArCiAgICAgICJsZEVudHJ5XDAzMl9cblwwMjZSZWN1cnNpdmVNYXBGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAwNVwwMjI0XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyJS5tYXBfZm9yX3Byb3RvMl90IiArCiAgICAgICJlc3QuVGVzdFJlY3Vyc2l2ZU1hcDpcMDAyOFwwMDFcIlwyMjFcMDA3XG5cMDE2Qml6YXJyb1Rlc3QiICsKICAgICAgIk1hcFwwMjJYXG5cMDI0aW50MzJfdG9faW50MzJfZmllbGRcMDMwXDAwMSBcMDAzKFwwMTMyOi5tYXBfIiArCiAgICAgICJmb3JfcHJvdG8yX3Rlc3QuQml6YXJyb1Rlc3RNYXAuSW50MzJUb0luIiArCiAgICAgICJ0MzJGaWVsZEVudHJ5XDAyMlpcblwwMjVpbnQzMl90b19zdHJpbmdfZmllbGRcMDMwXDAwMiIgKwogICAgICAiIFwwMDMoXDAxMzI7Lm1hcF9mb3JfcHJvdG8yX3Rlc3QuQml6YXJyb1Rlc3RNYSIgKwogICAgICAicC5JbnQzMlRvU3RyaW5nRmllbGRFbnRyeVwwMjJYXG5cMDI0aW50MzJfdG9fYnkiICsKICAgICAgInRlc19maWVsZFwwMzBcMDAzIFwwMDMoXDAxMzI6Lm1hcF9mb3JfcHJvdG8yX3Rlc3QuQmkiICsKICAgICAgInphcnJvVGVzdE1hcC5JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5XDAyMlZcblwwMjNpIiArCiAgICAgICJudDMyX3RvX2VudW1fZmllbGRcMDMwXDAwNCBcMDAzKFwwMTMyOS5tYXBfZm9yX3Byb3RvIiArCiAgICAgICIyX3Rlc3QuQml6YXJyb1Rlc3RNYXAuSW50MzJUb0VudW1GaWVsZEVuIiArCiAgICAgICJ0cnlcMDIyXFxcblwwMjZpbnQzMl90b19tZXNzYWdlX2ZpZWxkXDAzMFwwMDUgXDAwMyhcMDEzMjwubWEiICsKICAgICAgInBfZm9yX3Byb3RvMl90ZXN0LkJpemFycm9UZXN0TWFwLkludDMyVG8iICsKICAgICAgIk1lc3NhZ2VGaWVsZEVudHJ5XDAyMlpcblwwMjVzdHJpbmdfdG9faW50MzJfZmllIiArCiAgICAgICJsZFwwMzBcMDA2IFwwMDMoXDAxMzI7Lm1hcF9mb3JfcHJvdG8yX3Rlc3QuQml6YXJyb1RlIiArCiAgICAgICJzdE1hcC5TdHJpbmdUb0ludDMyRmllbGRFbnRyeVwwMzI4XG5cMDI2SW50MzJUbyIgKwogICAgICAiSW50MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDE0OlwwMDI4XDAwMVwwMzI5XG5cMDI3SW50MzJUb1N0cmluZ0ZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI4XG5cMDI2SW50MzJUb0J5dCIgKwogICAgICAiZXNGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDUiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyN1xuXDAyNUludDMyVG9FbnVtRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMjpcblwwMzBJbnQzMlRvTWVzc2FnZUYiICsKICAgICAgImllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4IiArCiAgICAgICJcMDAxXDAzMjlcblwwMjdTdHJpbmdUb0ludDMyRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXCJcMzY1XDAxMFxuXDAyMlJlc2VydmVkQXNNYXBGaSIgKwogICAgICAiZWxkXDAyMjtcblwwMDJpZlwwMzBcMDAxIFwwMDMoXDAxMzIvLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmUiICsKICAgICAgInNlcnZlZEFzTWFwRmllbGQuSWZFbnRyeVwwMjJBXG5cMDA1Y29uc3RcMDMwXDAwMiBcMDAzKFwwMTMyIiArCiAgICAgICIyLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkIiArCiAgICAgICIuQ29uc3RFbnRyeVwwMjJFXG5cMDA3cHJpdmF0ZVwwMzBcMDAzIFwwMDMoXDAxMzI0Lm1hcF9mb3JfcCIgKwogICAgICAicm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuUHJpdmF0ZUVudCIgKwogICAgICAicnlcMDIyQVxuXDAwNWNsYXNzXDAzMFwwMDQgXDAwMyhcMDEzMjIubWFwX2Zvcl9wcm90bzJfdGVzdC4iICsKICAgICAgIlJlc2VydmVkQXNNYXBGaWVsZC5DbGFzc0VudHJ5XDAyMj1cblwwMDNpbnRcMDMwXDAwNSBcMDAzIiArCiAgICAgICIoXDAxMzIwLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpIiArCiAgICAgICJlbGQuSW50RW50cnlcMDIyP1xuXDAwNHZvaWRcMDMwXDAwNiBcMDAzKFwwMTMyMS5tYXBfZm9yX3BybyIgKwogICAgICAidG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkLlZvaWRFbnRyeVwwMjJDXG4iICsKICAgICAgIlwwMDZzdHJpbmdcMDMwXDAwNyBcMDAzKFwwMTMyMy5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2UiICsKICAgICAgInJ2ZWRBc01hcEZpZWxkLlN0cmluZ0VudHJ5XDAyMkVcblwwMDdwYWNrYWdlXDAzMFwwMTAgIiArCiAgICAgICJcMDAzKFwwMTMyNC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGIiArCiAgICAgICJpZWxkLlBhY2thZ2VFbnRyeVwwMjI/XG5cMDA0ZW51bVwwMzBcdCBcMDAzKFwwMTMyMS5tYXBfZm8iICsKICAgICAgInJfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkLkVudW1FbnQiICsKICAgICAgInJ5XDAyMj9cblwwMDRudWxsXDAzMFxuIFwwMDMoXDAxMzIxLm1hcF9mb3JfcHJvdG8yX3Rlc3QuUiIgKwogICAgICAiZXNlcnZlZEFzTWFwRmllbGQuTnVsbEVudHJ5XDAzMilcblwwMDdJZkVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMixcblxuQ29uc3RFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIuXG5cMDE0IiArCiAgICAgICJQcml2YXRlRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHIiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyLFxuXG5DbGFzc0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMipcblwwMTBJbnRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIrXG5cdFZvaWRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdCIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzItXG5cMDEzU3RyaW5nRW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLlxuXDAxNFBhY2thZ2VFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIrXG5cdEVuIiArCiAgICAgICJ1bUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIiICsKICAgICAgIitcblx0TnVsbEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyIiArCiAgICAgICI6XDAwMjhcMDAxXCJcMjUyXDAxN1xuXDAzN1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUiICsKICAgICAgIlwwMjJIXG5cMDAyaWZcMDMwXDAwMSBcMDAzKFwwMTMyPC5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5JZkVudHJ5XDAyMk5cblwwMDVjbyIgKwogICAgICAibnN0XDAzMFwwMDIgXDAwMyhcMDEzMj8ubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZCIgKwogICAgICAiQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuQ29uc3RFbnRyeVwwMjJSXG5cMDA3cHIiICsKICAgICAgIml2YXRlXDAzMFwwMDMgXDAwMyhcMDEzMkEubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnYiICsKICAgICAgImVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuUHJpdmF0ZUVudHJ5XDAyMk4iICsKICAgICAgIlxuXDAwNWNsYXNzXDAzMFwwMDQgXDAwMyhcMDEzMj8ubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlIiArCiAgICAgICJydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuQ2xhc3NFbnRyeVwwMjJKIiArCiAgICAgICJcblwwMDNpbnRcMDMwXDAwNSBcMDAzKFwwMTMyPS5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydiIgKwogICAgICAiZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5JbnRFbnRyeVwwMjJMXG5cMDA0dm8iICsKICAgICAgImlkXDAzMFwwMDYgXDAwMyhcMDEzMj4ubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEEiICsKICAgICAgInNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuVm9pZEVudHJ5XDAyMlBcblwwMDZzdHJpIiArCiAgICAgICJuZ1wwMzBcMDA3IFwwMDMoXDAxMzJALm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBIiArCiAgICAgICJzTWFwRmllbGRXaXRoRW51bVZhbHVlLlN0cmluZ0VudHJ5XDAyMlJcblwwMDdwYSIgKwogICAgICAiY2thZ2VcMDMwXDAxMCBcMDAzKFwwMTMyQS5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydiIgKwogICAgICAiZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5QYWNrYWdlRW50cnlcMDIyTCIgKwogICAgICAiXG5cMDA0ZW51bVwwMzBcdCBcMDAzKFwwMTMyPi5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VyIiArCiAgICAgICJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5FbnVtRW50cnlcMDIyTFxuXDAwNCIgKwogICAgICAibnVsbFwwMzBcbiBcMDAzKFwwMTMyPi5tYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmUiICsKICAgICAgImRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5OdWxsRW50cnlcMDMyalxuXDAwN0lmIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJOXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyPy5tYXBfIiArCiAgICAgICJmb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVuIiArCiAgICAgICJ1bVZhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMm1cblxuQ29uc3RFbnRyeVwwMjJcMDEzXG5cMDAzIiArCiAgICAgICJrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMk5cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI/Lm1hcF9mb3JfcHJvdG8iICsKICAgICAgIjJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlMiICsKICAgICAgImFtcGxlRW51bTpcMDAyOFwwMDFcMDMyb1xuXDAxNFByaXZhdGVFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFx0XDAyMk5cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI/Lm1hcF9mb3JfcHJvdG8yX3Rlc3QuIiArCiAgICAgICJSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVuIiArCiAgICAgICJ1bTpcMDAyOFwwMDFcMDMybVxuXG5DbGFzc0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMk5cblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShcMDE2Mj8ubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlcnZlZEEiICsKICAgICAgInNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bTpcMDAyOFwwMDFcMDMya1xuIiArCiAgICAgICJcMDEwSW50RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyTlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mj8uIiArCiAgICAgICJtYXBfZm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpIiArCiAgICAgICJ0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwwMzJsXG5cdFZvaWRFbnRyeVwwMjIiICsKICAgICAgIlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMk5cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI/Lm1hcF9mb3JfcHIiICsKICAgICAgIm90bzJfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHUiICsKICAgICAgImUuU2FtcGxlRW51bTpcMDAyOFwwMDFcMDMyblxuXDAxM1N0cmluZ0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXHRcMDIyTlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mj8ubWFwX2Zvcl9wcm90bzJfdGVzIiArCiAgICAgICJ0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlIiArCiAgICAgICJFbnVtOlwwMDI4XDAwMVwwMzJvXG5cMDE0UGFja2FnZUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMk5cbiIgKwogICAgICAiXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mj8ubWFwX2Zvcl9wcm90bzJfdGVzdC5SZXNlciIgKwogICAgICAidmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bTpcMDAyOCIgKwogICAgICAiXDAwMVwwMzJsXG5cdEVudW1FbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJOXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAxNjI/Lm1hcF9mb3JfcHJvdG8yX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpIiArCiAgICAgICJlbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmxcblx0TnVsbEUiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyTlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2Mj8ubWFwX2YiICsKICAgICAgIm9yX3Byb3RvMl90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnUiICsKICAgICAgIm1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwiXDAzMlxuXG5TYW1wbGVFbnVtXDAyMlwwMDVcblwwMDFBIiArCiAgICAgICJcMDIwXDAwMFwwMjJcMDA1XG5cMDAxQlwwMjBcMDAxQiFcblwwMTBtYXBfdGVzdEJcMDI1TWFwRm9yUHJvdG8yVGVzdFAiICsKICAgICAgInJvdG8iCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW50MzJUb0ludDMyRmllbGQiLCAiSW50MzJUb1N0cmluZ0ZpZWxkIiwgIkludDMyVG9CeXRlc0ZpZWxkIiwgIkludDMyVG9FbnVtRmllbGQiLCAiSW50MzJUb01lc3NhZ2VGaWVsZCIsICJTdHJpbmdUb0ludDMyRmllbGQiLCAiUmVxdWlyZWRNZXNzYWdlTWFwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfTWVzc2FnZVdpdGhSZXF1aXJlZEZpZWxkc19kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9NZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdE1hcF9SZXF1aXJlZE1lc3NhZ2VNYXBFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RNYXBfUmVxdWlyZWRNZXNzYWdlTWFwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJJbnQzMlRvSW50MzJGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFVua25vd25FbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RVbmtub3duRW51bVZhbHVlX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0VW5rbm93bkVudW1WYWx1ZV9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9UZXN0UmVjdXJzaXZlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiVmFsdWUiLCAiUmVjdXJzaXZlTWFwRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Rlc3RSZWN1cnNpdmVNYXBfUmVjdXJzaXZlTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9SZWN1cnNpdmVNYXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfVGVzdFJlY3Vyc2l2ZU1hcF9SZWN1cnNpdmVNYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW50MzJUb0ludDMyRmllbGQiLCAiSW50MzJUb1N0cmluZ0ZpZWxkIiwgIkludDMyVG9CeXRlc0ZpZWxkIiwgIkludDMyVG9FbnVtRmllbGQiLCAiSW50MzJUb01lc3NhZ2VGaWVsZCIsICJTdHJpbmdUb0ludDMyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSWYiLCAiQ29uc3QiLCAiUHJpdmF0ZSIsICJDbGFzc18iLCAiSW50IiwgIlZvaWQiLCAiU3RyaW5nIiwgIlBhY2thZ2UiLCAiRW51bSIsICJOdWxsIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JZkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfRW51bUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSWYiLCAiQ29uc3QiLCAiUHJpdmF0ZSIsICJDbGFzc18iLCAiSW50IiwgIlZvaWQiLCAiU3RyaW5nIiwgIlBhY2thZ2UiLCAiRW51bSIsICJOdWxsIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfZm9yX3Byb3RvMl90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ZvaWRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0VudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF9mb3JfcHJvdG8yX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX2Zvcl9wcm90bzJfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQDduLOLAxAAAAMQAAAoAAAAbWFwX3Rlc3QvTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfaW5pdGlhbGl6YXRpb25fb3JkZXJfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgbWFwX3Rlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QgewogIHByaXZhdGUgTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQobWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QucmVjdXJzaXZlRXh0ZW5zaW9uKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVDVVJTSVZFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxMDAxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAubWFwX3Rlc3QuTWVzc2FnZTEgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBtYXBfdGVzdC5NZXNzYWdlMSwKICAgICAgbWFwX3Rlc3QuTWVzc2FnZTE+IHJlY3Vyc2l2ZUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgbWFwX3Rlc3QuTWVzc2FnZTEuY2xhc3MsCiAgICAgICAgbWFwX3Rlc3QuTWVzc2FnZTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NZXNzYWdlMV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NZXNzYWdlMV9NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NZXNzYWdlMV9NYXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVkYWN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1JlZGFjdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG43Y29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfaW5pdGlhbGl6YXRpb24iICsKICAgICAgIl9vcmRlcl90ZXN0LnByb3RvXDAyMlwwMTBtYXBfdGVzdFwie1xuXDAxME1lc3NhZ2UxXDAyMiIgKwogICAgICAiM1xuXHRtYXBfZmllbGRcMDMwXDAwMSBcMDAzKFwwMTMyIC5tYXBfdGVzdC5NZXNzYWdlMS5NIiArCiAgICAgICJhcEZpZWxkRW50cnlcMDMyL1xuXHJNYXBGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxIiArCiAgICAgICIoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDEqXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIlwwMjBcblwwMTZSZWRhIiArCiAgICAgICJjdEFsbFR5cGVzOkRcblwwMjNyZWN1cnNpdmVfZXh0ZW5zaW9uXDAyMlwwMjIubWFwXyIgKwogICAgICAidGVzdC5NZXNzYWdlMVwwMzBcMzUxXDAwNyBcMDAxKFwwMTMyXDAyMi5tYXBfdGVzdC5NZXNzYWdlMSIgKwogICAgICAiQihcblwwMTBtYXBfdGVzdEJcMDMyTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QiICsKICAgICAgIlBcMDAxIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1hcEZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01lc3NhZ2UxX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NZXNzYWdlMV9NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZWRhY3RBbGxUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZWRhY3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZWRhY3RBbGxUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIHJlY3Vyc2l2ZUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDApKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAO0jdJQTsQkAE7EJABoAAABtYXBfdGVzdC9NYXBUZXN0UHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgbWFwX3Rlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgTWFwVGVzdFByb3RvIHsKICBwcml2YXRlIE1hcFRlc3RQcm90bygpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBUZXN0TWFwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF90ZXN0LlRlc3RNYXApCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvRW51bUZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGdldEludDMyVG9FbnVtRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1N0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRVaW50MzJUb0ludDMyRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVaW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0VWludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRVaW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVpbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50NjRUb0ludDMyRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50NjRUb0ludDMyRmllbGQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50NjRUb0ludDMyRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50NjRUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQ2NFRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5UZXN0TWFwfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1hcCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfdGVzdC5UZXN0TWFwKQogICAgICBUZXN0TWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWFwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNYXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIG1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlfQogICAgICovCiAgICBwdWJsaWMgZW51bSBFbnVtVmFsdWUKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5RVVggPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIFFVWCgzKSwKICAgICAgVU5SRUNPR05JWkVEKC0xKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlFVWCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUVVYX1ZBTFVFID0gMzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgRW51bVZhbHVlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBFbnVtVmFsdWUgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBWjsKICAgICAgICAgIGNhc2UgMzogcmV0dXJuIFFVWDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEVudW1WYWx1ZT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIEVudW1WYWx1ZT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEVudW1WYWx1ZT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIEVudW1WYWx1ZSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gRW51bVZhbHVlLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIGRlc2NyaXB0b3Igb2YgYW4gdW5yZWNvZ25pemVkIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbnVtVmFsdWVbXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgRW51bVZhbHVlIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6bWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUpCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBNZXNzYWdlVmFsdWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgaW50IGdldFZhbHVlKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VWYWx1ZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgICAgTWVzc2FnZVZhbHVlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTWVzc2FnZVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTWVzc2FnZVZhbHVlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VWYWx1ZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfTWVzc2FnZVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5jbGFzcywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxVRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAodmFsdWVfICE9IDApIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICh2YWx1ZV8gIT0gMCkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHZhbHVlXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIG90aGVyID0gKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgb2JqOwoKICAgICAgICBpZiAoZ2V0VmFsdWUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZBTFVFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRWYWx1ZSgpOwogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBidWlsZCgpIHsKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSByZXN1bHQgPSBuZXcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgobWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuZ2V0VmFsdWUoKSAhPSAwKSB7CiAgICAgICAgICAgIHNldFZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIHZhbHVlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICAgIHJldHVybiB2YWx1ZV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKGludCB2YWx1ZSkgewoKICAgICAgICAgIHZhbHVlXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJWYWx1ZSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVZhbHVlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TWVzc2FnZVZhbHVlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE1lc3NhZ2VWYWx1ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VWYWx1ZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VWYWx1ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX1NUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19CWVRFU19GSUVMRF9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0J5dGVzRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvQnl0ZXNGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19FTlVNX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb0VudW1GaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb0VudW1GaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJUb0VudW1GaWVsZF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPiBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUuVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUsIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZT4KICAgIGdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW50MzJUb0VudW1GaWVsZE1hcCgKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWUgZ2V0SW50MzJUb0VudW1GaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkVudW1WYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVJTlQzMl9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVWludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX1VpbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVpbnQzMlRvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmICh1aW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVaW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdWludDMyVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1VpbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVaW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldFVpbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0VWludDMyVG9JbnQzMkZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFVpbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UNjRfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDY0VG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50NjRUb0ludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQ2NFRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDY0VG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50NjRUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50NjRUb0ludDMyRmllbGQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50NjRUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDY0VG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50NjRUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQ2NFRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludDY0VG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSwKICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLAogICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLAogICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBVaW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSwKICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpbnQzMlRvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBpbnQzMlRvU3RyaW5nRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fID0gSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGludDMyVG9CeXRlc0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0VudW1GaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBzdHJpbmdUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVpbnQzMlRvSW50MzJGaWVsZF9fID0gVWludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCB1aW50MzJUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50NjRUb0ludDMyRmllbGRfXyA9IEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4LCBpbnQ2NFRvSW50MzJGaWVsZF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgb3RoZXIgPSAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19TVFJJTkdfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19CWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9UT19FTlVNX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fTUVTU0FHRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVJTlQzMl9UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDY0X1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5UZXN0TWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX3Rlc3QuVGVzdE1hcCkKICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVaW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuY2xhc3MsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIGJ1aWxkKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIHJlc3VsdCA9IG5ldyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9JbnQzMkZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9TdHJpbmdGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9CeXRlc0ZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0VudW1GaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDMyVG9NZXNzYWdlRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuYnVpbGQoSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ1RvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVpbnQzMlRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LnVpbnQzMlRvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludDY0VG9JbnQzMkZpZWxkXyA9IGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQ2NFRvSW50MzJGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvSW50MzJGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9TdHJpbmdGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0VudW1GaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPgogICAgICAgICAgICAgICAgaW50MzJUb01lc3NhZ2VGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fLmdldEtleSgpLCBzdHJpbmdUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdWludDMyVG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBVaW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICB1aW50MzJUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgdWludDMyVG9JbnQzMkZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludDY0VG9JbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQ2NFRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50NjRUb0ludDMyRmllbGRfXy5nZXRLZXkoKSwgaW50NjRUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gaW50MzJUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9JbnQzMkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvU3RyaW5nRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfID0gaW50MzJUb1N0cmluZ0ZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb1N0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9CeXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb0J5dGVzRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnQzMlRvQnl0ZXNGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9CeXRlc0ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9FbnVtRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9FbnVtRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkXyA9IGludDMyVG9FbnVtRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlPgogICAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICAgIGdldEludDMyVG9FbnVtRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gaW50MzJUb0VudW1GaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldEludDMyVG9FbnVtRmllbGRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0SW50MzJUb0VudW1GaWVsZFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvRW51bUZpZWxkVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRWYWx1ZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuRW51bVZhbHVlIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBpbnQzMlRvRW51bUZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5FbnVtVmFsdWUmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9FbnVtRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5FbnVtVmFsdWU+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEludDMyVG9FbnVtRmllbGRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGRWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuRW51bVZhbHVlJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvRW51bUZpZWxkVmFsdWUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLkVudW1WYWx1ZSZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0VudW1GaWVsZFZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBidWlsZChtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSB7IHJldHVybiAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlciBpbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyID0gbmV3IEludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyPiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oaW50MzJUb01lc3NhZ2VGaWVsZENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWVPckJ1aWxkZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZT4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5tYXBfdGVzdC5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGludDMyVG9NZXNzYWdlRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLm1hcF90ZXN0LlRlc3RNYXAuTWVzc2FnZVZhbHVlJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWU+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAubWFwX3Rlc3QuVGVzdE1hcC5NZXNzYWdlVmFsdWUmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUuQnVpbGRlciBwdXRJbnQzMlRvTWVzc2FnZUZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5NZXNzYWdlVmFsdWUubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgewogICAgICAgICAgZW50cnkgPSAoKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLk1lc3NhZ2VWYWx1ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuTWVzc2FnZVZhbHVlLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChzdHJpbmdUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ1RvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF8gPSBzdHJpbmdUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cmluZ1RvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAodWludDMyVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVpbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdWludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmICh1aW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHVpbnQzMlRvSW50MzJGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVpbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVpbnQzMlRvSW50MzJGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVpbnQzMlRvSW50MzJGaWVsZF8gPSB1aW50MzJUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1aW50MzJUb0ludDMyRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VWludDMyVG9JbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCBpbnQzMiZndDsgdWludDMyX3RvX2ludDMyX2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVWludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVaW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0VWludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRVaW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldFVpbnQzMlRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFVpbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFVpbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVaW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVWludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVVaW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVaW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIGludDMyJmd0OyB1aW50MzJfdG9faW50MzJfZmllbGQgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVpbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgaW50MzImZ3Q7IHVpbnQzMl90b19pbnQzMl9maWVsZCA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVWludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGludDY0VG9JbnQzMkZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKGludDY0VG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDY0VG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnQ2NFRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQ2NFRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50NjRUb0ludDMyRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQ2NFRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDY0VG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50NjRUb0ludDMyRmllbGRfID0gaW50NjRUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQ2NFRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQ2NFRvSW50MzJGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDY0VG9JbnQzMkZpZWxkKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQ2NFRvSW50MzJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50NjRUb0ludDMyRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQ2NFRvSW50MzJGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDY0VG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDY0VG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDY0VG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQzMiZndDsgaW50NjRfdG9faW50MzJfZmllbGQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDY0VG9JbnQzMkZpZWxkKAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDY0VG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDMyJmd0OyBpbnQ2NF90b19pbnQzMl9maWVsZCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50NjRUb0ludDMyRmllbGQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50MzImZ3Q7IGludDY0X3RvX2ludDMyX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQ2NFRvSW50MzJGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NFRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOm1hcF90ZXN0LlRlc3RNYXApCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF90ZXN0LlRlc3RNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25PckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX3Rlc3QuVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPi5tYXBfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lm1hcF90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCBnZXRPcHRpb25hbE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+Lm1hcF90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBVc2VkIHRvIHRlc3QgdGhhdCBhIG5lc3RlZCBidWlsZGVyIGNvbnRhaW5pbmcgbWFwIGZpZWxkcyB3aWxsIHByb3Blcmx5CiAgICogcHJvcGFnYXRlIHRoZSBvbkNoYW5nZSBldmVudCBhbmQgbWFyayBpdHMgcGFyZW50IGRpcnR5IHdoZW4gYSBjaGFuZ2UKICAgKiBpcyBtYWRlIHRvIGEgbWFwIGZpZWxkLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX3Rlc3QuVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX3Rlc3QuVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbikKICAgICAgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24uY2xhc3MsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIG9wdGlvbmFsTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5tYXBfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5tYXBfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lm1hcF90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXBPckJ1aWxkZXIgZ2V0T3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlXyA9PSBudWxsID8gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRPcHRpb25hbE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRPcHRpb25hbE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIG90aGVyID0gKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVXNlZCB0byB0ZXN0IHRoYXQgYSBuZXN0ZWQgYnVpbGRlciBjb250YWluaW5nIG1hcCBmaWVsZHMgd2lsbCBwcm9wZXJseQogICAgICogcHJvcGFnYXRlIHRoZSBvbkNoYW5nZSBldmVudCBhbmQgbWFyayBpdHMgcGFyZW50IGRpcnR5IHdoZW4gYSBjaGFuZ2UKICAgICAqIGlzIG1hZGUgdG8gYSBtYXAgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9ufQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX3Rlc3QuVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbikKICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTWVzc2FnZV8gPSBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIG9wdGlvbmFsTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlcj4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5tYXBfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5tYXBfdGVzdC5UZXN0TWFwIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTWVzc2FnZShtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lm1hcF90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxNZXNzYWdlKAogICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTWVzc2FnZShtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gIT0gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Lm1hcF90ZXN0LlRlc3RNYXAgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXBPckJ1aWxkZXIgZ2V0T3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ubWFwX3Rlc3QuVGVzdE1hcCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcCwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXAuQnVpbGRlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RNYXBPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0TWFwLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcC5CdWlsZGVyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uVGVzdE1hcE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfdGVzdC5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfdGVzdC5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBCaXphcnJvVGVzdE1hcE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfdGVzdC5CaXphcnJvVGVzdE1hcCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvSW50MzJGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9CeXRlc0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludDMyVG9FbnVtRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludDMyVG9NZXNzYWdlRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdUb0ludDMyRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldFN0cmluZ1RvSW50MzJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFN0cmluZ1RvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogYSBkZWNveSBvZiBUZXN0TWFwIGZvciB0ZXN0aW5nIHBhcnNpbmcgZXJyb3JzCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5CaXphcnJvVGVzdE1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJpemFycm9UZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgICBCaXphcnJvVGVzdE1hcE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQml6YXJyb1Rlc3RNYXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQml6YXJyb1Rlc3RNYXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBCaXphcnJvVGVzdE1hcCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBCaXphcnJvVGVzdE1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVE9fSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9JbnQzMkZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0ludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX1NUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICBpZiAoaW50MzJUb1N0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb1N0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9TdHJpbmdGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludDMyVG9TdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9UT19CWVRFU19GSUVMRF9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvQnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvQnl0ZXNGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9CeXRlc0ZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX0VOVU1fRklFTERfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvRW51bUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0VudW1GaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0VudW1GaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9FbnVtRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9FbnVtRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9FbnVtRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMlRvTWVzc2FnZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMlRvTWVzc2FnZUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb01lc3NhZ2VGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9NZXNzYWdlRmllbGRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICBpZiAoc3RyaW5nVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1RvSW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyaW5nVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLAogICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSwKICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKSwKICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCksCiAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCksCiAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18gPSBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaW50MzJUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfXyA9IEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgaW50MzJUb1N0cmluZ0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fID0gSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGludDMyVG9CeXRlc0ZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgaW50MzJUb0VudW1GaWVsZF9fID0gSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgaW50MzJUb0VudW1GaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXyA9IEludDMyVG9NZXNzYWdlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGludDMyVG9NZXNzYWdlRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fID0gU3RyaW5nVG9JbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBzdHJpbmdUb0ludDMyRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgb3RoZXIgPSAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX0lOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fQllURVNfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVE9fRU5VTV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX1RPX01FU1NBR0VfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19UT19JTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogYSBkZWNveSBvZiBUZXN0TWFwIGZvciB0ZXN0aW5nIHBhcnNpbmcgZXJyb3JzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5CaXphcnJvVGVzdE1hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcC5jbGFzcywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nVG9JbnQzMkZpZWxkKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvSW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvU3RyaW5nRmllbGRfID0gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvU3RyaW5nRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvQnl0ZXNGaWVsZF8gPSBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCk7CiAgICAgICAgICByZXN1bHQuaW50MzJUb0J5dGVzRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvRW51bUZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9FbnVtRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlRvTWVzc2FnZUZpZWxkXyA9IGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LmludDMyVG9NZXNzYWdlRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdUb0ludDMyRmllbGRfID0gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdUb0ludDMyRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXApIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBpbnQzMlRvSW50MzJGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9JbnQzMkZpZWxkX18uZ2V0S2V5KCksIGludDMyVG9JbnQzMkZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW50MzJUb1N0cmluZ0ZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvU3RyaW5nRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb1N0cmluZ0ZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW50MzJUb0J5dGVzRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIEludDMyVG9CeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldEtleSgpLCBpbnQzMlRvQnl0ZXNGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvRW51bUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9FbnVtRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb0VudW1GaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBpbnQzMlRvTWVzc2FnZUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfXy5nZXRLZXkoKSwgaW50MzJUb01lc3NhZ2VGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFN0cmluZ1RvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHN0cmluZ1RvSW50MzJGaWVsZF9fLmdldEtleSgpLCBzdHJpbmdUb0ludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0ludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9JbnQzMkZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgaW50MzJUb0ludDMyRmllbGRfID0gaW50MzJUb0ludDMyRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvSW50MzJGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvSW50MzJGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IGludDMyX3RvX2ludDMyX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9JbnQzMkZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvSW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9JbnQzMkZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBpbnQzMl90b19pbnQzMl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0ludDMyRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZUludDMyVG9JbnQzMkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgaW50MzJfdG9faW50MzJfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDMyVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50MzJUb1N0cmluZ0ZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9TdHJpbmdGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9TdHJpbmdGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvU3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9TdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9TdHJpbmdGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9TdHJpbmdGaWVsZF8gPSBpbnQzMlRvU3RyaW5nRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvU3RyaW5nRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb1N0cmluZ0ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX3N0cmluZ19maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb1N0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50MzJUb1N0cmluZ0ZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvU3RyaW5nRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludDMyVG9TdHJpbmdGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvU3RyaW5nRmllbGRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9TdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9TdHJpbmdGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19zdHJpbmdfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9TdHJpbmdGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb1N0cmluZ0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fc3RyaW5nX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvU3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvU3RyaW5nRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0J5dGVzRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9CeXRlc0ZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBpZiAoaW50MzJUb0J5dGVzRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0J5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnQzMlRvQnl0ZXNGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9CeXRlc0ZpZWxkXyA9IGludDMyVG9CeXRlc0ZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50MzJUb0J5dGVzRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb0J5dGVzRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50MzJUb0J5dGVzRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSB0eXBlcywgc2FtZSB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgaW50MzImZ3Q7IGludDMyX3RvX2J5dGVzX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnQzMlRvQnl0ZXNGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlRvQnl0ZXNGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0J5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9CeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9CeXRlc0ZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IHR5cGVzLCBzYW1lIHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBpbnQzMiZndDsgaW50MzJfdG9fYnl0ZXNfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEludDMyVG9CeXRlc0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0J5dGVzRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgdHlwZXMsIHNhbWUgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGludDMyJmd0OyBpbnQzMl90b19ieXRlc19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0J5dGVzRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvQnl0ZXNGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGludDMyVG9FbnVtRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEludDMyVG9FbnVtRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludDMyVG9FbnVtRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIGlmIChpbnQzMlRvRW51bUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb0VudW1GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludDMyVG9FbnVtRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnQzMlRvRW51bUZpZWxkXyA9IGludDMyVG9FbnVtRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnQzMlRvRW51bUZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludDMyVG9FbnVtRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJUb0VudW1GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRJbnQzMlRvRW51bUZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRJbnQzMlRvRW51bUZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9FbnVtRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX2VudW1fZmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvRW51bUZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb0VudW1GaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0SW50MzJUb0VudW1GaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9FbnVtRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19lbnVtX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMlRvRW51bUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlSW50MzJUb0VudW1GaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9FbnVtRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fZW51bV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJUb0VudW1GaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvRW51bUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9NZXNzYWdlRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50MzJUb01lc3NhZ2VGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50MzJUb01lc3NhZ2VGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgaWYgKGludDMyVG9NZXNzYWdlRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnQzMlRvTWVzc2FnZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghaW50MzJUb01lc3NhZ2VGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludDMyVG9NZXNzYWdlRmllbGRfID0gaW50MzJUb01lc3NhZ2VGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGludDMyVG9NZXNzYWdlRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJUb01lc3NhZ2VGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnQzMlRvTWVzc2FnZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldEludDMyVG9NZXNzYWdlRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldEludDMyVG9NZXNzYWdlRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0SW50MzJUb01lc3NhZ2VGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGRpZmZlcmVudCBrZXkgYW5kIHZhbHVlIHR5cGVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgaW50MzJfdG9fbWVzc2FnZV9maWVsZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEludDMyVG9NZXNzYWdlRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRJbnQzMlRvTWVzc2FnZUZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBkaWZmZXJlbnQga2V5IGFuZCB2YWx1ZSB0eXBlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IGludDMyX3RvX21lc3NhZ2VfZmllbGQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyVG9NZXNzYWdlRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVJbnQzMlRvTWVzc2FnZUZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJUb01lc3NhZ2VGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZGlmZmVyZW50IGtleSBhbmQgdmFsdWUgdHlwZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBpbnQzMl90b19tZXNzYWdlX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQzMlRvTWVzc2FnZUZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyVG9NZXNzYWdlRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBzdHJpbmdUb0ludDMyRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgaWYgKHN0cmluZ1RvSW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvSW50MzJGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBpZiAoc3RyaW5nVG9JbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdUb0ludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzdHJpbmdUb0ludDMyRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdUb0ludDMyRmllbGRfID0gc3RyaW5nVG9JbnQzMkZpZWxkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gc3RyaW5nVG9JbnQzMkZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1RvSW50MzJGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRTdHJpbmdUb0ludDMyRmllbGRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0U3RyaW5nVG9JbnQzMkZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBzYW1lIGtleSB0eXBlLCBkaWZmZXJlbnQgdmFsdWUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJ5dGVzJmd0OyBzdHJpbmdfdG9faW50MzJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHJpbmdUb0ludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFN0cmluZ1RvSW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdUb0ludDMyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogc2FtZSBrZXkgdHlwZSwgZGlmZmVyZW50IHZhbHVlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBieXRlcyZndDsgc3RyaW5nX3RvX2ludDMyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmdUb0ludDMyRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdUb0ludDMyRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIHNhbWUga2V5IHR5cGUsIGRpZmZlcmVudCB2YWx1ZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYnl0ZXMmZ3Q7IHN0cmluZ190b19pbnQzMl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nVG9JbnQzMkZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1RvSW50MzJGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOm1hcF90ZXN0LkJpemFycm9UZXN0TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfdGVzdC5CaXphcnJvVGVzdE1hcCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uQml6YXJyb1Rlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5CaXphcnJvVGVzdE1hcCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJpemFycm9UZXN0TWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEJpemFycm9UZXN0TWFwPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQml6YXJyb1Rlc3RNYXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCaXphcnJvVGVzdE1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCaXphcnJvVGVzdE1hcD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLkJpemFycm9UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUmVzZXJ2ZWRBc01hcEZpZWxkT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldElmQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSWYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJZk9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENvbnN0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zQ29uc3QoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UHJpdmF0ZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UHJpdmF0ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFByaXZhdGVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc18oKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q2xhc3NfTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Q2xhc3NfT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SW50T3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFZvaWRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFZvaWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0U3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFBhY2thZ2VPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRFbnVtKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bU1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW51bU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TnVsbENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGwoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TnVsbE1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVXNlZCB0byB0ZXN0IHRoYXQgamF2YSByZXNlcnZlZCB3b3JkcyBjYW4gYmUgdXNlZCBhcyBwcm90b2J1ZiBmaWVsZCBuYW1lcwogICAqIE5vdCBhbGwgcmVzZXJ2ZWQgd29yZHMgYXJlIHRlc3RlZCAodG8gYXZvaWQgYmxvYXQpIGJ1dCBpbnN0ZWFkIGFuIGFyYml0cmFyeQogICAqIHN1YnNldCBvZiB0aGVtIGNob3NlbiB0byBjb3ZlciB2YXJpb3VzIGtleXdvcmQgY2F0ZWdvcmllcyBsaWtlCiAgICogdHlwZSwgbW9kaWZpZXIsIGRlY2xhcmF0aW9uLCBldGMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXNlcnZlZEFzTWFwRmllbGQgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkKQogICAgICBSZXNlcnZlZEFzTWFwRmllbGRPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFJlc2VydmVkQXNNYXBGaWVsZC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBSZXNlcnZlZEFzTWFwRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBSZXNlcnZlZEFzTWFwRmllbGQoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUmVzZXJ2ZWRBc01hcEZpZWxkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKTsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpOwogICAgICAgIGNhc2UgOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJZkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JZkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBpZl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldElmKCkgewogICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpZl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldElmQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSWYoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SWZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SWYoKSB7CiAgICAgIHJldHVybiBnZXRJZk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJZk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldElmT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT05TVF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY29uc3RfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gY29uc3RfOwogICAgfQogICAgcHVibGljIGludCBnZXRDb25zdENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0KCkgewogICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q29uc3RNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJJVkFURV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Qcml2YXRlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHByaXZhdGVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRQcml2YXRlKCkgewogICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZSgpIHsKICAgICAgcmV0dXJuIGdldFByaXZhdGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQcml2YXRlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBjbGFzc19fOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRDbGFzc18oKSB7CiAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gY2xhc3NfXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NsYXNzXygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENsYXNzXygpIHsKICAgICAgcmV0dXJuIGdldENsYXNzX01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDbGFzc19NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDbGFzc19PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlRfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50KCkgewogICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50KCkgewogICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRJbnRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZPSURfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFZvaWREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2b2lkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Vm9pZCgpIHsKICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZvaWRfOwogICAgfQogICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFZvaWQoKSB7CiAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Vm9pZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRWb2lkT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRWb2lkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBzdHJpbmdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRTdHJpbmcoKSB7CiAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZygpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRTdHJpbmdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLQUdFX0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2FnZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSB7CiAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQYWNrYWdlKCkgewogICAgICByZXR1cm4gZ2V0UGFja2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFBhY2thZ2VNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEVudW0oKSB7CiAgICAgIGlmIChlbnVtXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RW51bUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRFbnVtKCkgewogICAgICByZXR1cm4gZ2V0RW51bU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEVudW1NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RW51bU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RW51bU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTnVsbERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG51bGxfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXROdWxsKCkgewogICAgICBpZiAobnVsbF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbnVsbF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE51bGxDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldE51bGwoKSB7CiAgICAgIHJldHVybiBnZXROdWxsTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldE51bGxNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE51bGxPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXROdWxsT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldElmKCksCiAgICAgICAgICBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCksCiAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKSwKICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKSwKICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLAogICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLAogICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLAogICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLAogICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKSwKICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCksCiAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpZl9fID0gSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGlmX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBjb25zdF9fID0gQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGNvbnN0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHByaXZhdGVfXyA9IFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIHByaXZhdGVfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBjbGFzc19fXyA9IENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgY2xhc3NfX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgaW50X18gPSBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGludF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB2b2lkX18gPSBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCB2b2lkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgc3RyaW5nX18gPSBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIHN0cmluZ19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBwYWNrYWdlX18gPSBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4LCBwYWNrYWdlX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGVudW1fXyA9IEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGVudW1fXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbnVsbF9fID0gTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIG51bGxfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBvdGhlciA9IChtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0SWYoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldElmKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRDb25zdCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFByaXZhdGUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFByaXZhdGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldENsYXNzXygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q2xhc3NfKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Vm9pZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Vm9pZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFBhY2thZ2UoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEVudW0oKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVudW0oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE51bGwoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE51bGwoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJRl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJZigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ09OU1RfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Q29uc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJJVkFURV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRQcml2YXRlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0xBU1NfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Q2xhc3NfKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEludCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWT0lEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFZvaWQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0UGFja2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBFTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEVudW0oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTlVMTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXROdWxsKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBVc2VkIHRvIHRlc3QgdGhhdCBqYXZhIHJlc2VydmVkIHdvcmRzIGNhbiBiZSB1c2VkIGFzIHByb3RvYnVmIGZpZWxkIG5hbWVzCiAgICAgKiBOb3QgYWxsIHJlc2VydmVkIHdvcmRzIGFyZSB0ZXN0ZWQgKHRvIGF2b2lkIGJsb2F0KSBidXQgaW5zdGVhZCBhbiBhcmJpdHJhcnkKICAgICAqIHN1YnNldCBvZiB0aGVtIGNob3NlbiB0byBjb3ZlciB2YXJpb3VzIGtleXdvcmQgY2F0ZWdvcmllcyBsaWtlCiAgICAgKiB0eXBlLCBtb2RpZmllciwgZGVjbGFyYXRpb24sIGV0Yy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUlmKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKTsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU51bGwoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuY2xhc3MsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlmXyA9IGludGVybmFsR2V0SWYoKTsKICAgICAgICAgIHJlc3VsdC5pZl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvbnN0XyA9IGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICAgIHJlc3VsdC5jb25zdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByaXZhdGVfID0gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNsYXNzX18gPSBpbnRlcm5hbEdldENsYXNzXygpOwogICAgICAgICAgcmVzdWx0LmNsYXNzX18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludF8gPSBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgcmVzdWx0LmludF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnZvaWRfID0gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICByZXN1bHQudm9pZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ18gPSBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgcmVzdWx0LnN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBhY2thZ2VfID0gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmVudW1fID0gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgICByZXN1bHQuZW51bV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm51bGxfID0gaW50ZXJuYWxHZXROdWxsKCk7CiAgICAgICAgICByZXN1bHQubnVsbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaWZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpZl9fLmdldEtleSgpLCBpZl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNvbnN0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY29uc3RfXy5nZXRLZXkoKSwgY29uc3RfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBwcml2YXRlX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHByaXZhdGVfXy5nZXRLZXkoKSwgcHJpdmF0ZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNsYXNzX19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY2xhc3NfX18uZ2V0S2V5KCksIGNsYXNzX19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50X18uZ2V0S2V5KCksIGludF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHZvaWRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgdm9pZF9fLmdldEtleSgpLCB2b2lkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgc3RyaW5nX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBzdHJpbmdfXy5nZXRLZXkoKSwgc3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcGFja2FnZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBwYWNrYWdlX18uZ2V0S2V5KCksIHBhY2thZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBlbnVtX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGVudW1fXy5nZXRLZXkoKSwgZW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG51bGxfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbnVsbF9fLmdldEtleSgpLCBudWxsX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIGlmXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpZl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGlmXyA9IGlmXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaWZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SWYoKSB7CiAgICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldElmTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJZk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJZk9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySWYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUlmKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dElmKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbElmKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjb25zdF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbnN0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY29uc3RfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q29uc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldENvbnN0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29uc3QoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dENvbnN0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENvbnN0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHByaXZhdGVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKSB7CiAgICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpIHsKICAgICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgICAgcHJpdmF0ZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcml2YXRlXy5pc011dGFibGUoKSkgewogICAgICAgICAgcHJpdmF0ZV8gPSBwcml2YXRlXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRQcml2YXRlKCkgewogICAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UHJpdmF0ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByaXZhdGVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJpdmF0ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVQcml2YXRlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQcml2YXRlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY2xhc3NfXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKSB7CiAgICAgICAgaWYgKGNsYXNzX18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzX187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIGNsYXNzX18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWNsYXNzX18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNsYXNzX18gPSBjbGFzc19fLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDbGFzc19NYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDbGFzc18oKSB7CiAgICAgICAgcmV0dXJuIGdldENsYXNzX01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRDbGFzc19NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDbGFzc19PckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlQ2xhc3NfKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbENsYXNzXygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKSB7CiAgICAgICAgaWYgKGludF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkgewogICAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICAgIGludF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWludF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGludF8gPSBpbnRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbnRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0SW50KCkgewogICAgICAgIHJldHVybiBnZXRJbnRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEludE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJbnQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZvaWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKSB7CiAgICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdm9pZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpIHsKICAgICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgICAgdm9pZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF2b2lkXy5pc011dGFibGUoKSkgewogICAgICAgICAgdm9pZF8gPSB2b2lkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdm9pZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRWb2lkKCkgewogICAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Vm9pZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFZvaWRPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVm9pZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVWb2lkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxWb2lkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKSB7CiAgICAgICAgaWYgKHN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ18gPSBzdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFN0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0U3RyaW5nTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0U3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkgewogICAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKSB7CiAgICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICAgIHBhY2thZ2VfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghcGFja2FnZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHBhY2thZ2VfID0gcGFja2FnZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHBhY2thZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2FnZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2FnZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UGFja2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldFBhY2thZ2VNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2thZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlUGFja2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0UGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsUGFja2FnZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudW1fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKSB7CiAgICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW51bV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgICAgZW51bV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlbnVtXy5pc011dGFibGUoKSkgewogICAgICAgICAgZW51bV8gPSBlbnVtXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZW51bV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEVudW0oKSB7CiAgICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldEVudW1NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEVudW1PckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RW51bU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCB1aW50MzImZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBudWxsXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkgewogICAgICAgIGlmIChudWxsXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGxfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKSB7CiAgICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICAgIG51bGxfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbnVsbF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG51bGxfID0gbnVsbF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG51bGxfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVsbENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TnVsbCgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGdldE51bGxNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHVpbnQzMiZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bGwoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTnVsbCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgdWludDMyJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTnVsbCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBSZXNlcnZlZEFzTWFwRmllbGQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldElmQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SWZNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJZigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJZk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldElmT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldElmT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWZWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWZWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0SWZWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldElmVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDb25zdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q29uc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q29uc3RNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENvbnN0VmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENvbnN0VmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENvbnN0VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDb25zdFZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUHJpdmF0ZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQcml2YXRlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UHJpdmF0ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFByaXZhdGVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQcml2YXRlVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UHJpdmF0ZVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQcml2YXRlVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zQ2xhc3NfKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Q2xhc3NfKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzX01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q2xhc3NfVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENsYXNzX1ZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRDbGFzc19WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldENsYXNzX1ZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRJbnRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJbnRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SW50VmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnRWYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEludFZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRWb2lkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Vm9pZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFZvaWRWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0Vm9pZFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRWb2lkVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0U3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0U3RyaW5nVmFsdWUoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZ1ZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRTdHJpbmdWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1ZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zUGFja2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQYWNrYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0UGFja2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFBhY2thZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFBhY2thZ2VWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrYWdlVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UGFja2FnZVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRQYWNrYWdlVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNFbnVtKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW51bU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEVudW0oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRFbnVtTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0RW51bU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEVudW1WYWx1ZU1hcCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRFbnVtVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE51bGxDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTnVsbCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldE51bGxNYXAoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldE51bGxPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TnVsbFZhbHVlTWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXROdWxsVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkKICAgICAgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCk7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgIGNhc2UgODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnVtKCk7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIG1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gU2FtcGxlRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkEgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEEoMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBCKDEpLAogICAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+QSA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCX1ZBTFVFID0gMTsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgU2FtcGxlRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgU2FtcGxlRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gQTsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEI7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxTYW1wbGVFbnVtPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgU2FtcGxlRW51bT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFNhbXBsZUVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBTYW1wbGVFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTYW1wbGVFbnVtLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIGRlc2NyaXB0b3Igb2YgYW4gdW5yZWNvZ25pemVkIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTYW1wbGVFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFNhbXBsZUVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBTYW1wbGVFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6bWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtKQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElGX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJZkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaWZfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgaWYgKGlmXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gaWZfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGlmVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgaWZWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldElmQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0lmKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldElmTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldElmKCkgewogICAgICByZXR1cm4gZ2V0SWZNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldElmTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpZlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gaWZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SWZWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0SWZWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldElmVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJZlZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldElmVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldElmVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTlNUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDb25zdERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY29uc3RfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgaWYgKGNvbnN0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gY29uc3RfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGNvbnN0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgY29uc3RWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldENvbnN0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0NvbnN0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENvbnN0KCkgewogICAgICByZXR1cm4gZ2V0Q29uc3RNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENvbnN0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBjb25zdFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q29uc3RWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0Q29uc3RWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldENvbnN0VmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDb25zdFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENvbnN0VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldENvbnN0VmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSVZBVEVfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcHJpdmF0ZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFByaXZhdGUoKSB7CiAgICAgIGlmIChwcml2YXRlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBwcml2YXRlXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBwcml2YXRlVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBwcml2YXRlVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQcml2YXRlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UHJpdmF0ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQcml2YXRlKCkgewogICAgICByZXR1cm4gZ2V0UHJpdmF0ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQcml2YXRlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gcHJpdmF0ZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQcml2YXRlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gcHJpdmF0ZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFByaXZhdGVWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldFByaXZhdGVWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UHJpdmF0ZVZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcml2YXRlVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIENsYXNzX0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gY2xhc3NfXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGNsYXNzX187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gY2xhc3NfVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkQ2xhc3NfTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGNsYXNzX1ZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRDbGFzc18oKSB7CiAgICAgIHJldHVybiBnZXRDbGFzc19NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldENsYXNzX01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q2xhc3NfT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q2xhc3NfT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBjbGFzc19WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldENsYXNzX1ZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0Q2xhc3NfVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRDbGFzc19WYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDbGFzc19WYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gaW50XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0SW50KCkgewogICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gaW50VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGludFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0SW50Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SW50KCkgewogICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0SW50TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gaW50VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRJbnRWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldEludFZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEludFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50VmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50VmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWT0lEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLkEuZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZvaWRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRWb2lkKCkgewogICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdm9pZF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdm9pZFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdm9pZFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVm9pZCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Vm9pZCgpIHsKICAgICAgcmV0dXJuIGdldFZvaWRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0Vm9pZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFZvaWRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFZvaWRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHZvaWRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZvaWRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Vm9pZFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRWb2lkVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRWb2lkVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFZvaWRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZFZhbHVlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Vm9pZFZhbHVlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gc3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gc3RyaW5nVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkU3RyaW5nTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHN0cmluZ1ZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRTdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0U3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBzdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFN0cmluZ1ZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0U3RyaW5nVmFsdWVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRTdHJpbmdWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTdHJpbmdWYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tBR0VfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uQS5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2FnZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSB7CiAgICAgIGlmIChwYWNrYWdlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBwYWNrYWdlXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5VTlJFQ09HTklaRUQpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRQYWNrYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNQYWNrYWdlKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0UGFja2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQYWNrYWdlKCkgewogICAgICByZXR1cm4gZ2V0UGFja2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXRQYWNrYWdlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gcGFja2FnZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRQYWNrYWdlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gcGFja2FnZVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFBhY2thZ2VWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldFBhY2thZ2VWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2FnZVZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrYWdlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrYWdlVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRW51bURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnVtXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RW51bSgpIHsKICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGVudW1fOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IGVudW1WYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRFbnVtTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGVudW1WYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VudW0oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEVudW0oKSB7CiAgICAgIHJldHVybiBnZXRFbnVtTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgIGdldEVudW1NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRFbnVtTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEVudW1PclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1WYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0RW51bVZhbHVlKCkgewogICAgICByZXR1cm4gZ2V0RW51bVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRFbnVtVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTnVsbERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfTnVsbEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5BLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBudWxsXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TnVsbCgpIHsKICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG51bGxfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IG51bGxWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIG51bGxWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE51bGxDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNOdWxsKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TnVsbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICBnZXROdWxsKCkgewogICAgICByZXR1cm4gZ2V0TnVsbE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgZ2V0TnVsbE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE51bGxNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXROdWxsT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXROdWxsT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbnVsbFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldE51bGxWYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE51bGxWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE51bGxWYWx1ZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXROdWxsVmFsdWVPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SWYoKSwKICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKSwKICAgICAgICAgIENvbnN0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLAogICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLAogICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0SW50KCksCiAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCksCiAgICAgICAgICBWb2lkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCksCiAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCksCiAgICAgICAgICBQYWNrYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLAogICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKSwKICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTApOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGlmX18gPSBJZkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgaWZfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNvbnN0X18gPSBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgY29uc3RfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgcHJpdmF0ZV9fID0gUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgcHJpdmF0ZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGNsYXNzX19fID0gQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBjbGFzc19fXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbnRfXyA9IEludERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgaW50X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHZvaWRfXyA9IFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIHZvaWRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBzdHJpbmdfXyA9IFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNywgc3RyaW5nX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHBhY2thZ2VfXyA9IFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIHBhY2thZ2VfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZW51bV9fID0gRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZW51bV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBudWxsX18gPSBOdWxsRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgbnVsbF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgb3RoZXIgPSAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SWYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldENvbnN0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDb25zdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UHJpdmF0ZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0Q2xhc3NfKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRDbGFzc18oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEludCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRWb2lkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0UGFja2FnZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UGFja2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TnVsbCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TnVsbCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElGX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldElmKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDT05TVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDb25zdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUklWQVRFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFByaXZhdGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDTEFTU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRDbGFzc18oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZPSURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Vm9pZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRQYWNrYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RW51bSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOVUxMX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE51bGwoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJZigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50KCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVWb2lkKCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUVudW0oKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVOdWxsKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuY2xhc3MsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaWZfID0gaW50ZXJuYWxHZXRJZigpOwogICAgICAgICAgcmVzdWx0LmlmXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY29uc3RfID0gaW50ZXJuYWxHZXRDb25zdCgpOwogICAgICAgICAgcmVzdWx0LmNvbnN0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJpdmF0ZV8gPSBpbnRlcm5hbEdldFByaXZhdGUoKTsKICAgICAgICAgIHJlc3VsdC5wcml2YXRlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXyA9IGludGVybmFsR2V0Q2xhc3NfKCk7CiAgICAgICAgICByZXN1bHQuY2xhc3NfXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50XyA9IGludGVybmFsR2V0SW50KCk7CiAgICAgICAgICByZXN1bHQuaW50Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudm9pZF8gPSBpbnRlcm5hbEdldFZvaWQoKTsKICAgICAgICAgIHJlc3VsdC52b2lkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXyA9IGludGVybmFsR2V0U3RyaW5nKCk7CiAgICAgICAgICByZXN1bHQuc3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGFja2FnZV8gPSBpbnRlcm5hbEdldFBhY2thZ2UoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrYWdlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZW51bV8gPSBpbnRlcm5hbEdldEVudW0oKTsKICAgICAgICAgIHJlc3VsdC5lbnVtXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubnVsbF8gPSBpbnRlcm5hbEdldE51bGwoKTsKICAgICAgICAgIHJlc3VsdC5udWxsXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJZigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0Q29uc3QoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0UHJpdmF0ZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldENsYXNzXygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEludCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRWb2lkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFBhY2thZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0RW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXROdWxsKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaWZfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIElmRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBpZl9fLmdldEtleSgpLCBpZl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNvbnN0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBDb25zdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY29uc3RfXy5nZXRLZXkoKSwgY29uc3RfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBwcml2YXRlX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBQcml2YXRlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIHByaXZhdGVfXy5nZXRLZXkoKSwgcHJpdmF0ZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGNsYXNzX19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgY2xhc3NfX18uZ2V0S2V5KCksIGNsYXNzX19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGludF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgaW50X18uZ2V0S2V5KCksIGludF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHZvaWRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgdm9pZF9fLmdldEtleSgpLCB2b2lkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgc3RyaW5nX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBzdHJpbmdfXy5nZXRLZXkoKSwgc3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgcGFja2FnZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBwYWNrYWdlX18uZ2V0S2V5KCksIHBhY2thZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBlbnVtX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIGVudW1fXy5nZXRLZXkoKSwgZW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG51bGxfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbnVsbF9fLmdldEtleSgpLCBudWxsX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGlmXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpIHsKICAgICAgICBpZiAoaWZfID09IG51bGwpIHsKICAgICAgICAgIGlmXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSWZEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpZl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGlmXyA9IGlmXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaWZfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJZk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0SWYoKSB7CiAgICAgICAgcmV0dXJuIGdldElmTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldElmTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRJZk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRJZigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRJZk9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gaWZWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaWYgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SWZPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlmVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldElmVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRJZlZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRJZlZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRJZlZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldElmKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SWZWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0SWYoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySWYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSWYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUlmKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUlmKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSWZNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJZigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgaWZWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpZiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSWYoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZElmTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJZigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVJZlZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJZlZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGlmID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxJZlZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSWYoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNvbnN0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbnN0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpIHsKICAgICAgICBpZiAoY29uc3RfID09IG51bGwpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgQ29uc3REZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjb25zdF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGNvbnN0XyA9IGNvbnN0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY29uc3RfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRDb25zdE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Q29uc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldENvbnN0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldENvbnN0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRDb25zdE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRDb25zdCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDb25zdE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gY29uc3RWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY29uc3QgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Q29uc3RPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbnN0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldENvbnN0VmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRDb25zdFZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRDb25zdFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRDb25zdFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENvbnN0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RWYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q29uc3RWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Q29uc3QoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29uc3QoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQ29uc3QoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNvbnN0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUNvbnN0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkQ29uc3RNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDb25zdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgY29uc3RWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjb25zdCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsQ29uc3QoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZENvbnN0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDb25zdCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVDb25zdFZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDb25zdFZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNvbnN0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxDb25zdFZhbHVlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ29uc3QoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHByaXZhdGVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKSB7CiAgICAgICAgaWYgKHByaXZhdGVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgUHJpdmF0ZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpIHsKICAgICAgICBpZiAocHJpdmF0ZV8gPT0gbnVsbCkgewogICAgICAgICAgcHJpdmF0ZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFByaXZhdGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcml2YXRlXy5pc011dGFibGUoKSkgewogICAgICAgICAgcHJpdmF0ZV8gPSBwcml2YXRlXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcHJpdmF0ZV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRQcml2YXRlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ByaXZhdGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQcml2YXRlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRQcml2YXRlKCkgewogICAgICAgIHJldHVybiBnZXRQcml2YXRlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UHJpdmF0ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UHJpdmF0ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UHJpdmF0ZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwcml2YXRlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFByaXZhdGVWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFByaXZhdGVWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UHJpdmF0ZVZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFByaXZhdGVWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQcml2YXRlKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcml2YXRlVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFByaXZhdGUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJpdmF0ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcHJpdmF0ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUHJpdmF0ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUHJpdmF0ZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVQcml2YXRlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUHJpdmF0ZU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQcml2YXRlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHByaXZhdGVWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwcml2YXRlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQcml2YXRlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRQcml2YXRlTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQcml2YXRlKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZVByaXZhdGVWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFByaXZhdGVWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHByaXZhdGUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFByaXZhdGVWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVByaXZhdGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGNsYXNzX187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkgewogICAgICAgIGlmIChjbGFzc19fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgQ2xhc3NfRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBpZiAoY2xhc3NfXyA9PSBudWxsKSB7CiAgICAgICAgICBjbGFzc19fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBDbGFzc19EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjbGFzc19fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBjbGFzc19fID0gY2xhc3NfXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gY2xhc3NfXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldENsYXNzX01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Q2xhc3NfKCkgewogICAgICAgIHJldHVybiBnZXRDbGFzc19NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Q2xhc3NfTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0Q2xhc3NfKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldENsYXNzX09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGNsYXNzX1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRDbGFzc19PclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc19WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0Q2xhc3NfVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRDbGFzc19WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0Q2xhc3NfVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldENsYXNzX1ZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldENsYXNzX1ZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRDbGFzc18oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Q2xhc3NfVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldENsYXNzXygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDbGFzc18oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUNsYXNzXygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUNsYXNzXygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZENsYXNzX01hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGNsYXNzID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRDbGFzc18oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBjbGFzc19WYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsQ2xhc3NfKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRDbGFzc19NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVDbGFzc19WYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUNsYXNzXygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgY2xhc3MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dENsYXNzX1ZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQ2xhc3NfKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBjbGFzcyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsQ2xhc3NfVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVDbGFzc18oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGludF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0SW50KCkgewogICAgICAgIGlmIChpbnRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgSW50RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludCgpIHsKICAgICAgICBpZiAoaW50XyA9PSBudWxsKSB7CiAgICAgICAgICBpbnRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBJbnREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbnRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbnRfID0gaW50Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gaW50XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEludENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRJbnRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldEludCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW50TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRJbnRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEludE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldEludE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEludCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGludFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0SW50T3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEludFZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0SW50VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldEludFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0SW50VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludFZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludFZhbHVlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbnQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlSW50KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgaW50ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBpbnRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBpbnQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkSW50TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlSW50VmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0SW50VmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGludCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50VmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZvaWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKSB7CiAgICAgICAgaWYgKHZvaWRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVm9pZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdm9pZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpIHsKICAgICAgICBpZiAodm9pZF8gPT0gbnVsbCkgewogICAgICAgICAgdm9pZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFZvaWREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF2b2lkXy5pc011dGFibGUoKSkgewogICAgICAgICAgdm9pZF8gPSB2b2lkXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdm9pZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRWb2lkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZvaWQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRWb2lkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRWb2lkKCkgewogICAgICAgIHJldHVybiBnZXRWb2lkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0Vm9pZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0Vm9pZE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0Vm9pZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2b2lkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFZvaWRWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFZvaWRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0Vm9pZFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFZvaWRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRWb2lkKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWb2lkVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFZvaWQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVm9pZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgdm9pZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVm9pZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVm9pZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVWb2lkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVm9pZE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRWb2lkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZvaWRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyB2b2lkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxWb2lkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRWb2lkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVWb2lkKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZVZvaWRWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFZvaWRWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHZvaWQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFZvaWRWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVZvaWQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHN0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkgewogICAgICAgIGlmIChzdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpIHsKICAgICAgICBpZiAoc3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBzdHJpbmdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBzdHJpbmdfID0gc3RyaW5nXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gc3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldFN0cmluZ01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldFN0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkU3RyaW5nTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwptYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIGdldFN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFN0cmluZ1ZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRTdHJpbmdWYWx1ZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRTdHJpbmdWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1ZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGFyZSBhbHNvIHByb3RvIGtleXdvcmRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBzdHJpbmcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTdHJpbmdWYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRTdHJpbmdNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBzdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxTdHJpbmcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFN0cmluZ01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZVN0cmluZ1ZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBhcmUgYWxzbyBwcm90byBrZXl3b3JkcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgc3RyaW5nID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRTdHJpbmdWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgYXJlIGFsc28gcHJvdG8ga2V5d29yZHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHN0cmluZyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHBhY2thZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKSB7CiAgICAgICAgaWYgKHBhY2thZ2VfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgUGFja2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFja2FnZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpIHsKICAgICAgICBpZiAocGFja2FnZV8gPT0gbnVsbCkgewogICAgICAgICAgcGFja2FnZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFBhY2thZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwYWNrYWdlXy5pc011dGFibGUoKSkgewogICAgICAgICAgcGFja2FnZV8gPSBwYWNrYWdlXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gcGFja2FnZV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BhY2thZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRQYWNrYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXRQYWNrYWdlKCkgewogICAgICAgIHJldHVybiBnZXRQYWNrYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0UGFja2FnZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0UGFja2FnZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0UGFja2FnZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrYWdlVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFBhY2thZ2VWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFBhY2thZ2VWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0UGFja2FnZVZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFBhY2thZ2VWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRQYWNrYWdlKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQYWNrYWdlVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFBhY2thZ2UoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgcGFja2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUGFja2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlUGFja2FnZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVQYWNrYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkUGFja2FnZU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRQYWNrYWdlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHBhY2thZ2VWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBwYWNrYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxQYWNrYWdlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRQYWNrYWdlTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVQYWNrYWdlKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZVBhY2thZ2VWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFBhY2thZ2VWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IHBhY2thZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFBhY2thZ2VWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVBhY2thZ2UoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudW1fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKSB7CiAgICAgICAgaWYgKGVudW1fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW51bV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBpZiAoZW51bV8gPT0gbnVsbCkgewogICAgICAgICAgZW51bV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIEVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlbnVtXy5pc011dGFibGUoKSkgewogICAgICAgICAgZW51bV8gPSBlbnVtXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZW51bV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW51bSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldEVudW0oKSB7CiAgICAgICAgcmV0dXJuIGdldEVudW1NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgIGdldEVudW1NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0RW51bU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBlbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBnZXRFbnVtT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0RW51bVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0RW51bVZhbHVlKCkgewogICAgICAgIHJldHVybiBnZXRFbnVtVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRFbnVtVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRFbnVtVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1vc3QgcmVjZW50IEphdmEgcmVzZXJ2ZWQgd29yZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgZW51bSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0RW51bSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGVudW1WYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEVudW1NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlRW51bVZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRW51bSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTW9zdCByZWNlbnQgSmF2YSByZXNlcnZlZCB3b3JkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBlbnVtID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNb3N0IHJlY2VudCBKYXZhIHJlc2VydmVkIHdvcmQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IGVudW0gPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG51bGxfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKSB7CiAgICAgICAgaWYgKG51bGxfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTnVsbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpIHsKICAgICAgICBpZiAobnVsbF8gPT0gbnVsbCkgewogICAgICAgICAgbnVsbF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE51bGxEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFudWxsXy5pc011dGFibGUoKSkgewogICAgICAgICAgbnVsbF8gPSBudWxsXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbnVsbF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdWxsQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc051bGwoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXROdWxsTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPgogICAgICBnZXROdWxsKCkgewogICAgICAgIHJldHVybiBnZXROdWxsTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgZ2V0TnVsbE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkTnVsbE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCm1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0gZ2V0TnVsbE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TnVsbCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE51bGxWYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE51bGxWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0TnVsbFZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE51bGxWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXROdWxsKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsVmFsdWVPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdWxsVmFsdWVPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE51bGwoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTnVsbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogbnVsbCBpcyBub3QgYSAncmVzZXJ2ZWQgd29yZCcgcGVyIHNlIGJ1dCBhcyBhIGxpdGVyYWwgbmVlZHMgc2ltaWxhciBjYXJlCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtJmd0OyBudWxsID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTnVsbCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTnVsbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bT4KICAgICAgICAgIGdldE11dGFibGVOdWxsKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkTnVsbE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXROdWxsKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIG51bGxWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBudWxsIGlzIG5vdCBhICdyZXNlcnZlZCB3b3JkJyBwZXIgc2UgYnV0IGFzIGEgbGl0ZXJhbCBuZWVkcyBzaW1pbGFyIGNhcmUKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW0mZ3Q7IG51bGwgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxOdWxsKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWROdWxsTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVOdWxsKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TXV0YWJsZU51bGxWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE51bGxWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG51bGwgaXMgbm90IGEgJ3Jlc2VydmVkIHdvcmQnIHBlciBzZSBidXQgYXMgYSBsaXRlcmFsIG5lZWRzIHNpbWlsYXIgY2FyZQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bSZndDsgbnVsbCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE51bGxWYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU51bGwoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTptYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBNYXBDb250YWluZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6bWFwX3Rlc3QuTWFwQ29udGFpbmVyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE15TWFwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc015TWFwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TXlNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRNeU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRNeU1hcE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE15TWFwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm90b2NvbGJ1ZmZlcnMvcHJvdG9idWYvaXNzdWVzLzk3ODUKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIG1hcF90ZXN0Lk1hcENvbnRhaW5lcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1hcENvbnRhaW5lciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czptYXBfdGVzdC5NYXBDb250YWluZXIpCiAgICAgIE1hcENvbnRhaW5lck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTWFwQ29udGFpbmVyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE1hcENvbnRhaW5lcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE1hcENvbnRhaW5lcigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBNYXBDb250YWluZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NYXBDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1ZX01BUF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWFwQ29udGFpbmVyX015TWFwRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG15TWFwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRNeU1hcCgpIHsKICAgICAgaWYgKG15TWFwXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbXlNYXBfOwogICAgfQogICAgcHVibGljIGludCBnZXRNeU1hcENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNeU1hcCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNeU1hcE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE15TWFwKCkgewogICAgICByZXR1cm4gZ2V0TXlNYXBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TXlNYXBNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE15TWFwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TXlNYXBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKSwKICAgICAgICAgIE15TWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBteU1hcF9fID0gTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIG15TWFwX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgb3RoZXIgPSAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lcikgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldE15TWFwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNeU1hcCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1ZX01BUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNeU1hcCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogaHR0cHM6Ly9naXRodWIuY29tL3Byb3RvY29sYnVmZmVycy9wcm90b2J1Zi9pc3N1ZXMvOTc4NQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX3Rlc3QuTWFwQ29udGFpbmVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6bWFwX3Rlc3QuTWFwQ29udGFpbmVyKQogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NYXBDb250YWluZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyLmNsYXNzLCBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgYnVpbGQoKSB7CiAgICAgICAgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgcmVzdWx0ID0gbmV3IG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAobWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm15TWFwXyA9IGludGVybmFsR2V0TXlNYXAoKTsKICAgICAgICAgIHJlc3VsdC5teU1hcF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20obWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNeU1hcCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgbXlNYXBfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE15TWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBteU1hcF9fLmdldEtleSgpLCBteU1hcF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG15TWFwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE15TWFwKCkgewogICAgICAgIGlmIChteU1hcF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbXlNYXBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKSB7CiAgICAgICAgaWYgKG15TWFwXyA9PSBudWxsKSB7CiAgICAgICAgICBteU1hcF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE15TWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbXlNYXBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBteU1hcF8gPSBteU1hcF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG15TWFwXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE15TWFwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTXlNYXAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TXlNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE15TWFwKCkgewogICAgICAgIHJldHVybiBnZXRNeU1hcE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNeU1hcE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE15TWFwT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck15TWFwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU15TWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVNeU1hcCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TXlNYXAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNeU1hcCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTptYXBfdGVzdC5NYXBDb250YWluZXIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOm1hcF90ZXN0Lk1hcENvbnRhaW5lcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG1hcF90ZXN0Lk1hcFRlc3RQcm90by5NYXBDb250YWluZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWFwVGVzdFByb3RvLk1hcENvbnRhaW5lciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1hcENvbnRhaW5lcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNYXBDb250YWluZXI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBNYXBDb250YWluZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNYXBDb250YWluZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWFwQ29udGFpbmVyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NYXBUZXN0UHJvdG8uTWFwQ29udGFpbmVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9NZXNzYWdlVmFsdWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfVWludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9VaW50MzJUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQ2NFRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50NjRUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0VudW1GaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Db25zdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfUHJpdmF0ZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9DbGFzc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSW50RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfVm9pZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfRW51bUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfTnVsbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Db25zdEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSW50RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfRW51bUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX051bGxFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWFwQ29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWFwQ29udGFpbmVyX015TWFwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWFwQ29udGFpbmVyX015TWFwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcblwiY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdC5wcm90b1wwMjJcMDEwbWEiICsKICAgICAgInBfdGVzdFwiXDI2Mlx0XG5cMDA3VGVzdE1hcFwwMjJGXG5cMDI0aW50MzJfdG9faW50MzJfZmllIiArCiAgICAgICJsZFwwMzBcMDAxIFwwMDMoXDAxMzIoLm1hcF90ZXN0LlRlc3RNYXAuSW50MzJUb0ludDMyIiArCiAgICAgICJGaWVsZEVudHJ5XDAyMkhcblwwMjVpbnQzMl90b19zdHJpbmdfZmllbGRcMDMwXDAwMiBcMDAzKCIgKwogICAgICAiXDAxMzIpLm1hcF90ZXN0LlRlc3RNYXAuSW50MzJUb1N0cmluZ0ZpZWxkRSIgKwogICAgICAibnRyeVwwMjJGXG5cMDI0aW50MzJfdG9fYnl0ZXNfZmllbGRcMDMwXDAwMyBcMDAzKFwwMTMyKC5tYXAiICsKICAgICAgIl90ZXN0LlRlc3RNYXAuSW50MzJUb0J5dGVzRmllbGRFbnRyeVwwMjJEXG5cMDIzIiArCiAgICAgICJpbnQzMl90b19lbnVtX2ZpZWxkXDAzMFwwMDQgXDAwMyhcMDEzMlwnLm1hcF90ZXN0LlRlcyIgKwogICAgICAidE1hcC5JbnQzMlRvRW51bUZpZWxkRW50cnlcMDIySlxuXDAyNmludDMyX3RvX20iICsKICAgICAgImVzc2FnZV9maWVsZFwwMzBcMDA1IFwwMDMoXDAxMzIqLm1hcF90ZXN0LlRlc3RNYXAuSW4iICsKICAgICAgInQzMlRvTWVzc2FnZUZpZWxkRW50cnlcMDIySFxuXDAyNXN0cmluZ190b19pbnQzIiArCiAgICAgICIyX2ZpZWxkXDAzMFwwMDYgXDAwMyhcMDEzMikubWFwX3Rlc3QuVGVzdE1hcC5TdHJpbmdUIiArCiAgICAgICJvSW50MzJGaWVsZEVudHJ5XDAyMkhcblwwMjV1aW50MzJfdG9faW50MzJfZmllbCIgKwogICAgICAiZFwwMzBcMDA3IFwwMDMoXDAxMzIpLm1hcF90ZXN0LlRlc3RNYXAuVWludDMyVG9JbnQzMiIgKwogICAgICAiRmllbGRFbnRyeVwwMjJGXG5cMDI0aW50NjRfdG9faW50MzJfZmllbGRcMDMwXDAxMCBcMDAzKFwwMTMiICsKICAgICAgIjIoLm1hcF90ZXN0LlRlc3RNYXAuSW50NjRUb0ludDMyRmllbGRFbnQiICsKICAgICAgInJ5XDAzMlwwMzVcblwwMTRNZXNzYWdlVmFsdWVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNVwwMzI4XG5cMDI2SW50IiArCiAgICAgICIzMlRvSW50MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI5XG5cMDI3SW50MzJUb1N0cmluZ0ZpZWxkRW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI4XG5cMDI2SW50MzJUIiArCiAgICAgICJvQnl0ZXNGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzJUXG5cMDI1SW50MzJUb0VudW1GaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXkiICsKICAgICAgIlwwMzBcMDAxIFwwMDEoXDAwNVwwMjIqXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyXDAzMy5tYXBfdGVzdC5UZXN0TWFwIiArCiAgICAgICIuRW51bVZhbHVlOlwwMDI4XDAwMVwwMzJaXG5cMDMwSW50MzJUb01lc3NhZ2VGaWVsZEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjItXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNi5tYXBfdGVzIiArCiAgICAgICJ0LlRlc3RNYXAuTWVzc2FnZVZhbHVlOlwwMDI4XDAwMVwwMzI5XG5cMDI3U3RyaW5nVG9JbiIgKwogICAgICAidDMyRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSgiICsKICAgICAgIlwwMDU6XDAwMjhcMDAxXDAzMjlcblwwMjdVaW50MzJUb0ludDMyRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFxyXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXDAzMjhcblwwMjZJbnQ2NFRvSW50MzIiICsKICAgICAgIkZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDIiICsKICAgICAgIjhcMDAxXCIvXG5cdEVudW1WYWx1ZVwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDBcMDIyXDAwN1xuXDAwM0JBUlwwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVoiICsKICAgICAgIlwwMjBcMDAyXDAyMlwwMDdcblwwMDNRVVhcMDIwXDAwM1wiS1xuXDAzNFRlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXQiICsKICAgICAgImlvblwwMjIrXG5cMDIwb3B0aW9uYWxfbWVzc2FnZVwwMzBcMDAxIFwwMDEoXDAxMzJcMDIxLm1hcF90ZXN0IiArCiAgICAgICIuVGVzdE1hcFwiXDMxN1wwMDZcblwwMTZCaXphcnJvVGVzdE1hcFwwMjJNXG5cMDI0aW50MzJfdG9fIiArCiAgICAgICJpbnQzMl9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzIvLm1hcF90ZXN0LkJpemFycm9UZXN0IiArCiAgICAgICJNYXAuSW50MzJUb0ludDMyRmllbGRFbnRyeVwwMjJPXG5cMDI1aW50MzJfdG9fcyIgKwogICAgICAidHJpbmdfZmllbGRcMDMwXDAwMiBcMDAzKFwwMTMyMC5tYXBfdGVzdC5CaXphcnJvVGVzdCIgKwogICAgICAiTWFwLkludDMyVG9TdHJpbmdGaWVsZEVudHJ5XDAyMk1cblwwMjRpbnQzMl90b18iICsKICAgICAgImJ5dGVzX2ZpZWxkXDAzMFwwMDMgXDAwMyhcMDEzMi8ubWFwX3Rlc3QuQml6YXJyb1Rlc3QiICsKICAgICAgIk1hcC5JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5XDAyMktcblwwMjNpbnQzMl90b19lIiArCiAgICAgICJudW1fZmllbGRcMDMwXDAwNCBcMDAzKFwwMTMyLi5tYXBfdGVzdC5CaXphcnJvVGVzdE1hIiArCiAgICAgICJwLkludDMyVG9FbnVtRmllbGRFbnRyeVwwMjJRXG5cMDI2aW50MzJfdG9fbWVzcyIgKwogICAgICAiYWdlX2ZpZWxkXDAzMFwwMDUgXDAwMyhcMDEzMjEubWFwX3Rlc3QuQml6YXJyb1Rlc3RNYSIgKwogICAgICAicC5JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlcMDIyT1xuXDAyNXN0cmluZ190b18iICsKICAgICAgImludDMyX2ZpZWxkXDAzMFwwMDYgXDAwMyhcMDEzMjAubWFwX3Rlc3QuQml6YXJyb1Rlc3QiICsKICAgICAgIk1hcC5TdHJpbmdUb0ludDMyRmllbGRFbnRyeVwwMzI4XG5cMDI2SW50MzJUb0luIiArCiAgICAgICJ0MzJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoIiArCiAgICAgICJcMDE0OlwwMDI4XDAwMVwwMzI5XG5cMDI3SW50MzJUb1N0cmluZ0ZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwwMzI4XG5cMDI2SW50MzJUb0J5dGVzIiArCiAgICAgICJGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyN1xuXDAyNUludDMyVG9FbnVtRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdCIgKwogICAgICAiXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXDAzMjpcblwwMzBJbnQzMlRvTWVzc2FnZUZpZSIgKwogICAgICAibGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzIiICsKICAgICAgIjlcblwwMjdTdHJpbmdUb0ludDMyRmllbGRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjIiICsKICAgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTQ6XDAwMjhcMDAxXCJcMjA3XDAxMFxuXDAyMlJlc2VydmVkQXNNYXBGaWVsIiArCiAgICAgICJkXDAyMjBcblwwMDJpZlwwMzBcMDAxIFwwMDMoXDAxMzIkLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaSIgKwogICAgICAiZWxkLklmRW50cnlcMDIyNlxuXDAwNWNvbnN0XDAzMFwwMDIgXDAwMyhcMDEzMlwnLm1hcF90ZXN0LlJlIiArCiAgICAgICJzZXJ2ZWRBc01hcEZpZWxkLkNvbnN0RW50cnlcMDIyOlxuXDAwN3ByaXZhdGVcMDMwXDAwMyIgKwogICAgICAiIFwwMDMoXDAxMzIpLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZC5Qcml2YSIgKwogICAgICAidGVFbnRyeVwwMjI2XG5cMDA1Y2xhc3NcMDMwXDAwNCBcMDAzKFwwMTMyXCcubWFwX3Rlc3QuUmVzZXJ2IiArCiAgICAgICJlZEFzTWFwRmllbGQuQ2xhc3NFbnRyeVwwMjIyXG5cMDAzaW50XDAzMFwwMDUgXDAwMyhcMDEzMiUubSIgKwogICAgICAiYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuSW50RW50cnlcMDIyNFxuXDAwNHYiICsKICAgICAgIm9pZFwwMzBcMDA2IFwwMDMoXDAxMzImLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZC4iICsKICAgICAgIlZvaWRFbnRyeVwwMjI4XG5cMDA2c3RyaW5nXDAzMFwwMDcgXDAwMyhcMDEzMigubWFwX3Rlc3QuUmVzIiArCiAgICAgICJlcnZlZEFzTWFwRmllbGQuU3RyaW5nRW50cnlcMDIyOlxuXDAwN3BhY2thZ2VcMDMwXDAxMCIgKwogICAgICAiIFwwMDMoXDAxMzIpLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZC5QYWNrYSIgKwogICAgICAiZ2VFbnRyeVwwMjI0XG5cMDA0ZW51bVwwMzBcdCBcMDAzKFwwMTMyJi5tYXBfdGVzdC5SZXNlcnZlIiArCiAgICAgICJkQXNNYXBGaWVsZC5FbnVtRW50cnlcMDIyNFxuXDAwNG51bGxcMDMwXG4gXDAwMyhcMDEzMiYubWEiICsKICAgICAgInBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGQuTnVsbEVudHJ5XDAzMilcblwwMDdJIiArCiAgICAgICJmRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMiwiICsKICAgICAgIlxuXG5Db25zdEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyIiArCiAgICAgICI6XDAwMjhcMDAxXDAzMi5cblwwMTRQcml2YXRlRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWwiICsKICAgICAgInVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLFxuXG5DbGFzc0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXDAzMipcblwwMTBJbnRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzIrXG5cdFZvaWRFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDI4XDAwMVwwMzItXG5cMDEzU3RyaW5nRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyLlxuXDAxNFBhIiArCiAgICAgICJja2FnZUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFxyOlwwMDIiICsKICAgICAgIjhcMDAxXDAzMitcblx0RW51bUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXHI6XDAwMjhcMDAxXDAzMitcblx0TnVsbEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsIiArCiAgICAgICJ1ZVwwMzBcMDAyIFwwMDEoXHI6XDAwMjhcMDAxXCJcMzE2XHJcblwwMzdSZXNlcnZlZEFzTWFwRmllbGRXaXRoRSIgKwogICAgICAibnVtVmFsdWVcMDIyPVxuXDAwMmlmXDAzMFwwMDEgXDAwMyhcMDEzMjEubWFwX3Rlc3QuUmVzZXJ2ZWQiICsKICAgICAgIkFzTWFwRmllbGRXaXRoRW51bVZhbHVlLklmRW50cnlcMDIyQ1xuXDAwNWNvbnN0IiArCiAgICAgICJcMDMwXDAwMiBcMDAzKFwwMTMyNC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoIiArCiAgICAgICJFbnVtVmFsdWUuQ29uc3RFbnRyeVwwMjJHXG5cMDA3cHJpdmF0ZVwwMzBcMDAzIFwwMDMoXDAxMzI2LiIgKwogICAgICAibWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZSIgKwogICAgICAiLlByaXZhdGVFbnRyeVwwMjJDXG5cMDA1Y2xhc3NcMDMwXDAwNCBcMDAzKFwwMTMyNC5tYXBfdGVzdC4iICsKICAgICAgIlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuQ2xhc3NFbnQiICsKICAgICAgInJ5XDAyMj9cblwwMDNpbnRcMDMwXDAwNSBcMDAzKFwwMTMyMi5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwIiArCiAgICAgICJGaWVsZFdpdGhFbnVtVmFsdWUuSW50RW50cnlcMDIyQVxuXDAwNHZvaWRcMDMwXDAwNiBcMDAzKCIgKwogICAgICAiXDAxMzIzLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtViIgKwogICAgICAiYWx1ZS5Wb2lkRW50cnlcMDIyRVxuXDAwNnN0cmluZ1wwMzBcMDA3IFwwMDMoXDAxMzI1Lm1hcF90ZXMiICsKICAgICAgInQuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TdHJpbmciICsKICAgICAgIkVudHJ5XDAyMkdcblwwMDdwYWNrYWdlXDAzMFwwMTAgXDAwMyhcMDEzMjYubWFwX3Rlc3QuUmVzZXJ2IiArCiAgICAgICJlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlBhY2thZ2VFbnRyeVwwMjJBIiArCiAgICAgICJcblwwMDRlbnVtXDAzMFx0IFwwMDMoXDAxMzIzLm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWUiICsKICAgICAgImxkV2l0aEVudW1WYWx1ZS5FbnVtRW50cnlcMDIyQVxuXDAwNG51bGxcMDMwXG4gXDAwMyhcMDEzMiIgKwogICAgICAiMy5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbCIgKwogICAgICAidWUuTnVsbEVudHJ5XDAzMl9cblwwMDdJZkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkNcblwwMDUiICsKICAgICAgInZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjQubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWwiICsKICAgICAgImRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmJcblxuQ29uc3RFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI0Lm1hcF90ZSIgKwogICAgICAic3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbCIgKwogICAgICAiZUVudW06XDAwMjhcMDAxXDAzMmRcblwwMTRQcml2YXRlRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyQyIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyNC5tYXBfdGVzdC5SZXNlcnZlZEFzTWFwRmkiICsKICAgICAgImVsZFdpdGhFbnVtVmFsdWUuU2FtcGxlRW51bTpcMDAyOFwwMDFcMDMyYlxuXG5DbGFzcyIgKwogICAgICAiRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyQ1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjQubWFwXyIgKwogICAgICAidGVzdC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbSIgKwogICAgICAicGxlRW51bTpcMDAyOFwwMDFcMDMyYFxuXDAxMEludEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkNcblwwMDUiICsKICAgICAgInZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjQubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWwiICsKICAgICAgImRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmFcblx0Vm9pZEVudCIgKwogICAgICAicnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyQ1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjQubWFwX3RlcyIgKwogICAgICAidC5SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlLlNhbXBsZSIgKwogICAgICAiRW51bTpcMDAyOFwwMDFcMDMyY1xuXDAxM1N0cmluZ0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkNcblwwMDUiICsKICAgICAgInZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MjQubWFwX3Rlc3QuUmVzZXJ2ZWRBc01hcEZpZWwiICsKICAgICAgImRXaXRoRW51bVZhbHVlLlNhbXBsZUVudW06XDAwMjhcMDAxXDAzMmRcblwwMTRQYWNrYWdlIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJDXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyNC5tYXBfIiArCiAgICAgICJ0ZXN0LlJlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWUuU2FtIiArCiAgICAgICJwbGVFbnVtOlwwMDI4XDAwMVwwMzJhXG5cdEVudW1FbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJDXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI0Lm1hcF90ZXN0LlJlc2VydmVkQXNNYXBGaWUiICsKICAgICAgImxkV2l0aEVudW1WYWx1ZS5TYW1wbGVFbnVtOlwwMDI4XDAwMVwwMzJhXG5cdE51bGxFbiIgKwogICAgICAidHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMkNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjI0Lm1hcF90ZSIgKwogICAgICAic3QuUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZS5TYW1wbCIgKwogICAgICAiZUVudW06XDAwMjhcMDAxXCJcMDMyXG5cblNhbXBsZUVudW1cMDIyXDAwNVxuXDAwMUFcMDIwXDAwMFwwMjJcMDA1XG5cMDAxQlwwMjBcMDAxXCJvXG4iICsKICAgICAgIlwwMTRNYXBDb250YWluZXJcMDIyMVxuXDAwNm15X21hcFwwMzBcMDAxIFwwMDMoXDAxMzIhLm1hcF90ZXN0IiArCiAgICAgICIuTWFwQ29udGFpbmVyLk15TWFwRW50cnlcMDMyLFxuXG5NeU1hcEVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxQlwwMzBcblwwMTBtYXBfdGUiICsKICAgICAgInN0QlwwMTRNYXBUZXN0UHJvdG9iXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJJbnQzMlRvSW50MzJGaWVsZCIsICJJbnQzMlRvU3RyaW5nRmllbGQiLCAiSW50MzJUb0J5dGVzRmllbGQiLCAiSW50MzJUb0VudW1GaWVsZCIsICJJbnQzMlRvTWVzc2FnZUZpZWxkIiwgIlN0cmluZ1RvSW50MzJGaWVsZCIsICJVaW50MzJUb0ludDMyRmllbGQiLCAiSW50NjRUb0ludDMyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX01lc3NhZ2VWYWx1ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb1N0cmluZ0ZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9CeXRlc0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQzMlRvTWVzc2FnZUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9TdHJpbmdUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX1VpbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfVWludDMyVG9JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9VaW50MzJUb0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9JbnQ2NFRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RNYXBfSW50NjRUb0ludDMyRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0TWFwX0ludDY0VG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Rlc3RPbkNoYW5nZUV2ZW50UHJvcGFnYXRpb25fZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfVGVzdE9uQ2hhbmdlRXZlbnRQcm9wYWdhdGlvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9UZXN0T25DaGFuZ2VFdmVudFByb3BhZ2F0aW9uX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbE1lc3NhZ2UiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW50MzJUb0ludDMyRmllbGQiLCAiSW50MzJUb1N0cmluZ0ZpZWxkIiwgIkludDMyVG9CeXRlc0ZpZWxkIiwgIkludDMyVG9FbnVtRmllbGQiLCAiSW50MzJUb01lc3NhZ2VGaWVsZCIsICJTdHJpbmdUb0ludDMyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb0J5dGVzRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9FbnVtRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9JbnQzMlRvRW51bUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfSW50MzJUb01lc3NhZ2VGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX0ludDMyVG9NZXNzYWdlRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfQml6YXJyb1Rlc3RNYXBfU3RyaW5nVG9JbnQzMkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9CaXphcnJvVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X0JpemFycm9UZXN0TWFwX1N0cmluZ1RvSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSWYiLCAiQ29uc3QiLCAiUHJpdmF0ZSIsICJDbGFzc18iLCAiSW50IiwgIlZvaWQiLCAiU3RyaW5nIiwgIlBhY2thZ2UiLCAiRW51bSIsICJOdWxsIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0lmRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfSWZFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NvbnN0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ByaXZhdGVFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0NsYXNzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0ludEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9JbnRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1ZvaWRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9TdHJpbmdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9QYWNrYWdlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX0VudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX051bGxFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZF9OdWxsRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkX051bGxFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIklmIiwgIkNvbnN0IiwgIlByaXZhdGUiLCAiQ2xhc3NfIiwgIkludCIsICJWb2lkIiwgIlN0cmluZyIsICJQYWNrYWdlIiwgIkVudW0iLCAiTnVsbCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSWZFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0lmRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JZkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NvbnN0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Db25zdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ29uc3RFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Qcml2YXRlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfQ2xhc3NFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0NsYXNzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9DbGFzc0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX0ludEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfSW50RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9JbnRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9Wb2lkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfU3RyaW5nRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9TdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX1BhY2thZ2VFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZXNlcnZlZEFzTWFwRmllbGRXaXRoRW51bVZhbHVlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9FbnVtRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfTnVsbEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVzZXJ2ZWRBc01hcEZpZWxkV2l0aEVudW1WYWx1ZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfTnVsbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1Jlc2VydmVkQXNNYXBGaWVsZFdpdGhFbnVtVmFsdWVfTnVsbEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NYXBDb250YWluZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWFwQ29udGFpbmVyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTXlNYXAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NYXBDb250YWluZXJfTXlNYXBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9NeU1hcEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01hcENvbnRhaW5lcl9NeU1hcEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAOC6Ha1MXwAATF8AABYAAABtYXBfdGVzdC9NZXNzYWdlMS5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9pbml0aWFsaXphdGlvbl9vcmRlcl90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBtYXBfdGVzdDsKCi8qKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5NZXNzYWdlMX0KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBNZXNzYWdlMSBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgTWVzc2FnZTE+IGltcGxlbWVudHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6bWFwX3Rlc3QuTWVzc2FnZTEpCiAgICBNZXNzYWdlMU9yQnVpbGRlciB7CnByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogIC8vIFVzZSBNZXNzYWdlMS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogIHByaXZhdGUgTWVzc2FnZTEoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8bWFwX3Rlc3QuTWVzc2FnZTEsID8+IGJ1aWxkZXIpIHsKICAgIHN1cGVyKGJ1aWxkZXIpOwogIH0KICBwcml2YXRlIE1lc3NhZ2UxKCkgewogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IE1lc3NhZ2UxKCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEluaXRpYWxpemF0aW9uT3JkZXJUZXN0LmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NZXNzYWdlMV9kZXNjcmlwdG9yOwogIH0KCiAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgaW50IG51bWJlcikgewogICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgY2FzZSAxOgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCk7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgfQogIH0KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgIHJldHVybiBtYXBfdGVzdC5NYXBJbml0aWFsaXphdGlvbk9yZGVyVGVzdC5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfTWVzc2FnZTFfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgIG1hcF90ZXN0Lk1lc3NhZ2UxLmNsYXNzLCBtYXBfdGVzdC5NZXNzYWdlMS5CdWlsZGVyLmNsYXNzKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgbWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01lc3NhZ2UxX01hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgZmFsc2UpOwogIH0KICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXBGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogIGludGVybmFsR2V0TWFwRmllbGQoKSB7CiAgICBpZiAobWFwRmllbGRfID09IG51bGwpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICB9CiAgICByZXR1cm4gbWFwRmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldE1hcEZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRmllbGQoCiAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldE1hcEZpZWxkKCkgewogICAgcmV0dXJuIGdldE1hcEZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0TWFwRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZ2V0TWFwRmllbGRPckRlZmF1bHQoCiAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewogICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICB9CiAgICByZXR1cm4gbWFwLmdldChrZXkpOwogIH0KCiAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxtYXBfdGVzdC5NZXNzYWdlMT4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKSwKICAgICAgICBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgMSk7CiAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzA5MTIsIG91dHB1dCk7CiAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICBzaXplID0gMDsKICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICBtYXBGaWVsZF9fID0gTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgIC5idWlsZCgpOwogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgbWFwRmllbGRfXyk7CiAgICB9CiAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICByZXR1cm4gc2l6ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgIGlmIChvYmogPT0gdGhpcykgewogICAgIHJldHVybiB0cnVlOwogICAgfQogICAgaWYgKCEob2JqIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWVzc2FnZTEpKSB7CiAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgIH0KICAgIG1hcF90ZXN0Lk1lc3NhZ2UxIG90aGVyID0gKG1hcF90ZXN0Lk1lc3NhZ2UxKSBvYmo7CgogICAgaWYgKCFpbnRlcm5hbEdldE1hcEZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSkpCiAgICAgIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgfQogICAgaW50IGhhc2ggPSA0MTsKICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgaWYgKCFpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgIHJldHVybiBoYXNoOwogIH0KCiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NZXNzYWdlMSBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1lc3NhZ2UxIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NZXNzYWdlMSBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWVzc2FnZTEgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWVzc2FnZTEgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWVzc2FnZTEgcGFyc2VGcm9tKAogICAgICBieXRlW10gZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWVzc2FnZTEgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NZXNzYWdlMSBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NZXNzYWdlMSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KCiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NZXNzYWdlMSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0Lk1lc3NhZ2UxIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuTWVzc2FnZTEgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIobWFwX3Rlc3QuTWVzc2FnZTEgcHJvdG90eXBlKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICB9CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICByZXR1cm4gYnVpbGRlcjsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgbWFwX3Rlc3QuTWVzc2FnZTF9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgbWFwX3Rlc3QuTWVzc2FnZTEsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfdGVzdC5NZXNzYWdlMSkKICAgICAgbWFwX3Rlc3QuTWVzc2FnZTFPckJ1aWxkZXIgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01lc3NhZ2UxX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X01lc3NhZ2UxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuTWVzc2FnZTEuY2xhc3MsIG1hcF90ZXN0Lk1lc3NhZ2UxLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfdGVzdC5NZXNzYWdlMS5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICB9CgogICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmNsZWFyKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEluaXRpYWxpemF0aW9uT3JkZXJUZXN0LmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9NZXNzYWdlMV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NZXNzYWdlMSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWVzc2FnZTEuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0Lk1lc3NhZ2UxIGJ1aWxkKCkgewogICAgICBtYXBfdGVzdC5NZXNzYWdlMSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5NZXNzYWdlMSBidWlsZFBhcnRpYWwoKSB7CiAgICAgIG1hcF90ZXN0Lk1lc3NhZ2UxIHJlc3VsdCA9IG5ldyBtYXBfdGVzdC5NZXNzYWdlMSh0aGlzKTsKICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgb25CdWlsdCgpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKG1hcF90ZXN0Lk1lc3NhZ2UxIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICByZXN1bHQubWFwRmllbGRfID0gaW50ZXJuYWxHZXRNYXBGaWVsZCgpOwogICAgICAgIHJlc3VsdC5tYXBGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICB9CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICBtYXBfdGVzdC5NZXNzYWdlMSwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgbWFwX3Rlc3QuTWVzc2FnZTEsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICBtYXBfdGVzdC5NZXNzYWdlMSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgbWFwX3Rlc3QuTWVzc2FnZTEsIFQ+IGV4dGVuc2lvbikgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX3Rlc3QuTWVzc2FnZTEpIHsKICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5NZXNzYWdlMSlvdGhlcik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5NZXNzYWdlMSBvdGhlcikgewogICAgICBpZiAob3RoZXIgPT0gbWFwX3Rlc3QuTWVzc2FnZTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgbWFwRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBtYXBGaWVsZF9fLmdldEtleSgpLCBtYXBGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gLy8gZmluYWxseQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPiBtYXBGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgaW50ZXJuYWxHZXRNYXBGaWVsZCgpIHsKICAgICAgaWYgKG1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkgewogICAgICBpZiAobWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICBtYXBGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIGlmICghbWFwRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgbWFwRmllbGRfID0gbWFwRmllbGRfLmNvcHkoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gbWFwRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0TWFwRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRNYXBGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IGdldE1hcEZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0TWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgIC5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRNdXRhYmxlTWFwRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgYm9vbGVhbiB2YWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBib29sJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwRmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX3Rlc3QuTWVzc2FnZTEpCiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX3Rlc3QuTWVzc2FnZTEpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuTWVzc2FnZTEgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5NZXNzYWdlMSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5NZXNzYWdlMSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2UxPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlMT4oKSB7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgTWVzc2FnZTEgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlMT4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZTE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBtYXBfdGVzdC5NZXNzYWdlMSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKfQoKUEsDBAoAAAAAAAAAIQAs+dVEpQQAAKUEAAAfAAAAbWFwX3Rlc3QvTWVzc2FnZTFPckJ1aWxkZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfaW5pdGlhbGl6YXRpb25fb3JkZXJfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgbWFwX3Rlc3Q7CgpwdWJsaWMgaW50ZXJmYWNlIE1lc3NhZ2UxT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfdGVzdC5NZXNzYWdlMSkKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPE1lc3NhZ2UxPiB7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIGludCBnZXRNYXBGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgYm9vbGVhbiBjb250YWluc01hcEZpZWxkKAogICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5Cb29sZWFuPgogIGdldE1hcEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuQm9vbGVhbj4KICBnZXRNYXBGaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIGJvb2wmZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gZ2V0TWFwRmllbGRPckRlZmF1bHQoCiAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgYm9vbCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgYm9vbGVhbiBnZXRNYXBGaWVsZE9yVGhyb3coCiAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKfQpQSwMECgAAAAAAAAAhAA0FJmHkMwAA5DMAABwAAABtYXBfdGVzdC9SZWRhY3RBbGxUeXBlcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL21hcF9pbml0aWFsaXphdGlvbl9vcmRlcl90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBtYXBfdGVzdDsKCi8qKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlc30KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBSZWRhY3RBbGxUeXBlcyBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOm1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzKQogICAgUmVkYWN0QWxsVHlwZXNPckJ1aWxkZXIgewpwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAvLyBVc2UgUmVkYWN0QWxsVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIFJlZGFjdEFsbFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgUmVkYWN0QWxsVHlwZXMoKSB7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgIHJldHVybiBuZXcgUmVkYWN0QWxsVHlwZXMoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gbWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1JlZGFjdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgIHJldHVybiBtYXBfdGVzdC5NYXBJbml0aWFsaXphdGlvbk9yZGVyVGVzdC5pbnRlcm5hbF9zdGF0aWNfbWFwX3Rlc3RfUmVkYWN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzLmNsYXNzLCBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICB9CgogIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgc2l6ZSA9IDA7CiAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgIHJldHVybiBzaXplOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcykpIHsKICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgfQogICAgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMgb3RoZXIgPSAobWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMpIG9iajsKCiAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICB9CiAgICBpbnQgaGFzaCA9IDQxOwogICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgcmV0dXJuIGhhc2g7CiAgfQoKICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgIGJ5dGVbXSBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogIH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBwcm90b3R5cGUpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogIH0KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgIHJldHVybiBidWlsZGVyOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czptYXBfdGVzdC5SZWRhY3RBbGxUeXBlcykKICAgICAgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXNPckJ1aWxkZXIgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1JlZGFjdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuaW50ZXJuYWxfc3RhdGljX21hcF90ZXN0X1JlZGFjdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMuY2xhc3MsIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICB9CgogICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIG1hcF90ZXN0Lk1hcEluaXRpYWxpemF0aW9uT3JkZXJUZXN0LmludGVybmFsX3N0YXRpY19tYXBfdGVzdF9SZWRhY3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIGJ1aWxkKCkgewogICAgICBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgIG1hcF90ZXN0LlJlZGFjdEFsbFR5cGVzIHJlc3VsdCA9IG5ldyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyh0aGlzKTsKICAgICAgb25CdWlsdCgpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMpIHsKICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcylvdGhlcik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBvdGhlcikgewogICAgICBpZiAob3RoZXIgPT0gbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHRyeSB7CiAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IC8vIGZpbmFsbHkKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6bWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMpCiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6bWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbWFwX3Rlc3QuUmVkYWN0QWxsVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcygpOwogIH0KCiAgcHVibGljIHN0YXRpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlZGFjdEFsbFR5cGVzPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZWRhY3RBbGxUeXBlcz4oKSB7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgUmVkYWN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZWRhY3RBbGxUeXBlcz4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVkYWN0QWxsVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBtYXBfdGVzdC5SZWRhY3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKfQoKUEsDBAoAAAAAAAAAIQCPvx6ZYQEAAGEBAAAlAAAAbWFwX3Rlc3QvUmVkYWN0QWxsVHlwZXNPckJ1aWxkZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tYXBfaW5pdGlhbGl6YXRpb25fb3JkZXJfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgbWFwX3Rlc3Q7CgpwdWJsaWMgaW50ZXJmYWNlIFJlZGFjdEFsbFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczptYXBfdGVzdC5SZWRhY3RBbGxUeXBlcykKICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7Cn0KUEsDBAoAAAAAAAAAIQAg/WB5vvMAAL7zAAApAAAAcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC9UZXN0Q2hlY2tVdGY4LmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jaGVja191dGY4LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90bzJfdGVzdF9jaGVja191dGY4OwoKcHVibGljIGZpbmFsIGNsYXNzIFRlc3RDaGVja1V0ZjggewogIHByaXZhdGUgVGVzdENoZWNrVXRmOCgpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBTdHJpbmdXcmFwcGVyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvMl90ZXN0X2NoZWNrX3V0ZjguU3RyaW5nV3JhcHBlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXEoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgcmVxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgcmVxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXAuCiAgICAgKi8KICAgIGludCBnZXRSZXBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBCeXRlcyhpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfdGVzdF9jaGVja191dGY4LlN0cmluZ1dyYXBwZXJ9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdXcmFwcGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvMl90ZXN0X2NoZWNrX3V0ZjguU3RyaW5nV3JhcHBlcikKICAgICAgU3RyaW5nV3JhcHBlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgU3RyaW5nV3JhcHBlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBTdHJpbmdXcmFwcGVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgU3RyaW5nV3JhcHBlcigpIHsKICAgICAgcmVxXyA9ICIiOwogICAgICBvcHRfID0gIiI7CiAgICAgIHJlcF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFN0cmluZ1dyYXBwZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfU3RyaW5nV3JhcHBlcl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9TdHJpbmdXcmFwcGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIuY2xhc3MsIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHJlcV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcmVxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIHJlcV8gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciByZXEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSByZXFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICByZXFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUF9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFoYXNSZXEoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCByZXFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIG9wdF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMywgcmVwXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIHJlcV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMiwgb3B0Xyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciBvdGhlciA9IChwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlcikgb2JqOwoKICAgICAgaWYgKGhhc1JlcSgpICE9IG90aGVyLmhhc1JlcSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXEoKSkgewogICAgICAgIGlmICghZ2V0UmVxKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0KCkgIT0gb3RoZXIuaGFzT3B0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdCgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzUmVxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5TdHJpbmdXcmFwcGVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5TdHJpbmdXcmFwcGVyKQogICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9TdHJpbmdXcmFwcGVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9TdHJpbmdXcmFwcGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyLmNsYXNzLCBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXFfID0gIiI7CiAgICAgICAgb3B0XyA9ICIiOwogICAgICAgIHJlcF8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9TdHJpbmdXcmFwcGVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciBidWlsZCgpIHsKICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciByZXN1bHQgPSBuZXcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxXyA9IHJlcV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0XyA9IG9wdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBfID0gcmVwXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlciBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguU3RyaW5nV3JhcHBlci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc1JlcSgpKSB7CiAgICAgICAgICByZXFfID0gb3RoZXIucmVxXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0KCkpIHsKICAgICAgICAgIG9wdF8gPSBvdGhlci5vcHRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBfID0gb3RoZXIucmVwXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcF8uYWRkQWxsKG90aGVyLnJlcF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWhhc1JlcSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgcmVxXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgb3B0XyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcF8uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCByZXFfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgcmVxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcmVxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIHJlcV8gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgcmVxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSByZXFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICByZXFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHJlcV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXEoKSB7CiAgICAgICAgcmVxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFJlcSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciByZXEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICByZXFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0KCkgewogICAgICAgIG9wdF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb3B0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwTGlzdCgpIHsKICAgICAgICByZXBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcENvdW50KCkgewogICAgICAgIHJldHVybiByZXBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBJc011dGFibGUoKTsKICAgICAgICByZXBfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIHJlcF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXAoKSB7CiAgICAgICAgcmVwXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBJc011dGFibGUoKTsKICAgICAgICByZXBfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvMl90ZXN0X2NoZWNrX3V0ZjguU3RyaW5nV3JhcHBlcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5TdHJpbmdXcmFwcGVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5TdHJpbmdXcmFwcGVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3RyaW5nV3JhcHBlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxTdHJpbmdXcmFwcGVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgU3RyaW5nV3JhcHBlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN0cmluZ1dyYXBwZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3RyaW5nV3JhcHBlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LlN0cmluZ1dyYXBwZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBCeXRlc1dyYXBwZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5CeXRlc1dyYXBwZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXEoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgcmVxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0UmVwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcC4KICAgICAqLwogICAgaW50IGdldFJlcENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguQnl0ZXNXcmFwcGVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnl0ZXNXcmFwcGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvMl90ZXN0X2NoZWNrX3V0ZjguQnl0ZXNXcmFwcGVyKQogICAgICBCeXRlc1dyYXBwZXJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEJ5dGVzV3JhcHBlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBCeXRlc1dyYXBwZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBCeXRlc1dyYXBwZXIoKSB7CiAgICAgIHJlcV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIG9wdF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIHJlcF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBCeXRlc1dyYXBwZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfQnl0ZXNXcmFwcGVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LmludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X0J5dGVzV3JhcHBlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIuY2xhc3MsIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgcmVxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgcmVxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXEoKSB7CiAgICAgIHJldHVybiByZXFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHQoKSB7CiAgICAgIHJldHVybiBvcHRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUF9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGdldFJlcExpc3QoKSB7CiAgICAgIHJldHVybiByZXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXAoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFoYXNSZXEoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMSwgcmVxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMiwgb3B0Xyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMywgcmVwXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDEsIHJlcV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoMiwgb3B0Xyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcocmVwXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBvdGhlciA9IChwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyKSBvYmo7CgogICAgICBpZiAoaGFzUmVxKCkgIT0gb3RoZXIuaGFzUmVxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlcSgpKSB7CiAgICAgICAgaWYgKCFnZXRSZXEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHQoKSAhPSBvdGhlci5oYXNPcHQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0KCkpIHsKICAgICAgICBpZiAoIWdldE9wdCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNSZXEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguQnl0ZXNXcmFwcGVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5CeXRlc1dyYXBwZXIpCiAgICAgICAgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlck9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfQnl0ZXNXcmFwcGVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9CeXRlc1dyYXBwZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlci5jbGFzcywgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgb3B0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICByZXBfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9CeXRlc1dyYXBwZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIGJ1aWxkKCkgewogICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIHJlc3VsdCA9IG5ldyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxXyA9IHJlcV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0XyA9IG9wdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBfID0gcmVwXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzUmVxKCkpIHsKICAgICAgICAgIHNldFJlcShvdGhlci5nZXRSZXEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHQoKSkgewogICAgICAgICAgc2V0T3B0KG90aGVyLmdldE9wdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcF8gPSBvdGhlci5yZXBfOwogICAgICAgICAgICByZXBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcF8uYWRkQWxsKG90aGVyLnJlcF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWhhc1JlcSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgcmVxXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgb3B0XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHYgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwXy5hZGQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgcmVxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSByZXEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVxKCkgewogICAgICAgIHJldHVybiByZXFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyByZXEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICByZXFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyByZXEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJlcV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRSZXEoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0KCkgewogICAgICAgIHJldHVybiBvcHRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLlByb3RvYnVmTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHJlcF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRSZXBMaXN0KCkgewogICAgICAgIHJlcF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIHJlcF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBJc011dGFibGUoKTsKICAgICAgICByZXBfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcCgpIHsKICAgICAgICByZXBfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvMl90ZXN0X2NoZWNrX3V0ZjguQnl0ZXNXcmFwcGVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzJfdGVzdF9jaGVja191dGY4LkJ5dGVzV3JhcHBlcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvMl90ZXN0X2NoZWNrX3V0ZjguVGVzdENoZWNrVXRmOC5CeXRlc1dyYXBwZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOC5UZXN0Q2hlY2tVdGY4LkJ5dGVzV3JhcHBlciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJ5dGVzV3JhcHBlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxCeXRlc1dyYXBwZXI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCeXRlc1dyYXBwZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCeXRlc1dyYXBwZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qnl0ZXNXcmFwcGVyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4LlRlc3RDaGVja1V0ZjguQnl0ZXNXcmFwcGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfU3RyaW5nV3JhcHBlcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X1N0cmluZ1dyYXBwZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfQnl0ZXNXcmFwcGVyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfQnl0ZXNXcmFwcGVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4pY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2NoZWNrX3V0ZjgucHIiICsKICAgICAgIm90b1wwMjJcMDI2cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOFwiNlxuXHJTdHJpbmdXcmEiICsKICAgICAgInBwZXJcMDIyXDAxM1xuXDAwM3JlcVwwMzBcMDAxIFwwMDIoXHRcMDIyXDAxM1xuXDAwM29wdFwwMzBcMDAyIFwwMDEoXHRcMDIyXDAxM1xuXDAwM3JlcFwwMzBcMDAzICIgKwogICAgICAiXDAwMyhcdFwiNVxuXDAxNEJ5dGVzV3JhcHBlclwwMjJcMDEzXG5cMDAzcmVxXDAzMFwwMDEgXDAwMihcMDE0XDAyMlwwMTNcblwwMDNvcHRcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAxNFwwMjJcMDEzXG5cMDAzcmVwXDAzMFwwMDMgXDAwMyhcMDE0QlwwMjJCXHJUZXN0Q2hlY2tVdGY4XDMzMFwwMDFcMDAxIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9TdHJpbmdXcmFwcGVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0ZjhfU3RyaW5nV3JhcHBlcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X1N0cmluZ1dyYXBwZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcSIsICJPcHQiLCAiUmVwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9CeXRlc1dyYXBwZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9CeXRlc1dyYXBwZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9CeXRlc1dyYXBwZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcSIsICJPcHQiLCAiUmVwIiwgfSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQB+GMTxssgAALLIAAAyAAAAcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplL1Rlc3RDaGVja1V0ZjhTaXplLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jaGVja191dGY4X3NpemUucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZTsKCnB1YmxpYyBmaW5hbCBjbGFzcyBUZXN0Q2hlY2tVdGY4U2l6ZSB7CiAgcHJpdmF0ZSBUZXN0Q2hlY2tVdGY4U2l6ZSgpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBTdHJpbmdXcmFwcGVyU2l6ZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuU3RyaW5nV3JhcHBlclNpemUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgcmVxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUmVxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXEoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHJlcS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwLgogICAgICovCiAgICBpbnQgZ2V0UmVwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwQnl0ZXMoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlN0cmluZ1dyYXBwZXJTaXplfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nV3JhcHBlclNpemUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlN0cmluZ1dyYXBwZXJTaXplKQogICAgICBTdHJpbmdXcmFwcGVyU2l6ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgU3RyaW5nV3JhcHBlclNpemUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgU3RyaW5nV3JhcHBlclNpemUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBTdHJpbmdXcmFwcGVyU2l6ZSgpIHsKICAgICAgcmVxXyA9ICIiOwogICAgICBvcHRfID0gIiI7CiAgICAgIHJlcF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFN0cmluZ1dyYXBwZXJTaXplKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLmludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfU3RyaW5nV3JhcHBlclNpemVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZV9TdHJpbmdXcmFwcGVyU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZS5jbGFzcywgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHJlcV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcmVxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIHJlcV8gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciByZXEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSByZXFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICByZXFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUF9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuU3RyaW5nV3JhcHBlclNpemV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuU3RyaW5nV3JhcHBlclNpemUpCiAgICAgICAgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX1N0cmluZ1dyYXBwZXJTaXplX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX1N0cmluZ1dyYXBwZXJTaXplX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZS5jbGFzcywgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXFfID0gIiI7CiAgICAgICAgb3B0XyA9ICIiOwogICAgICAgIHJlcF8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX1N0cmluZ1dyYXBwZXJTaXplX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSBidWlsZCgpIHsKICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSByZXN1bHQgPSBuZXcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXFfID0gcmVxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRfID0gb3B0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlcF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcF8gPSByZXBfOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCByZXFfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBzdHJpbmcgcmVxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcmVxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIHJlcV8gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgcmVxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSByZXFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICByZXFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHJlcV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIHN0cmluZyByZXEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXEoKSB7CiAgICAgICAgcmVxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFJlcSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgc3RyaW5nIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciByZXEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICByZXFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0KCkgewogICAgICAgIG9wdF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb3B0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwTGlzdCgpIHsKICAgICAgICByZXBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcENvdW50KCkgewogICAgICAgIHJldHVybiByZXBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBJc011dGFibGUoKTsKICAgICAgICByZXBfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIHJlcF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXAoKSB7CiAgICAgICAgcmVwXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBJc011dGFibGUoKTsKICAgICAgICByZXBfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlN0cmluZ1dyYXBwZXJTaXplKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5TdHJpbmdXcmFwcGVyU2l6ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLlN0cmluZ1dyYXBwZXJTaXplIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3RyaW5nV3JhcHBlclNpemU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U3RyaW5nV3JhcHBlclNpemU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBTdHJpbmdXcmFwcGVyU2l6ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN0cmluZ1dyYXBwZXJTaXplPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN0cmluZ1dyYXBwZXJTaXplPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuU3RyaW5nV3JhcHBlclNpemUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBCeXRlc1dyYXBwZXJTaXplT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5CeXRlc1dyYXBwZXJTaXplKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgcmVxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUmVxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIHJlcSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFJlcExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXAuCiAgICAgKi8KICAgIGludCBnZXRSZXBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFJlcChpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuQnl0ZXNXcmFwcGVyU2l6ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ5dGVzV3JhcHBlclNpemUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLkJ5dGVzV3JhcHBlclNpemUpCiAgICAgIEJ5dGVzV3JhcHBlclNpemVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEJ5dGVzV3JhcHBlclNpemUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQnl0ZXNXcmFwcGVyU2l6ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEJ5dGVzV3JhcHBlclNpemUoKSB7CiAgICAgIHJlcV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIG9wdF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIHJlcF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBCeXRlc1dyYXBwZXJTaXplKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLmludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfQnl0ZXNXcmFwcGVyU2l6ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX0J5dGVzV3JhcHBlclNpemVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZS5jbGFzcywgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgcmVxXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgcmVxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyByZXEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXEoKSB7CiAgICAgIHJldHVybiByZXFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHQoKSB7CiAgICAgIHJldHVybiBvcHRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUF9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIGdldFJlcExpc3QoKSB7CiAgICAgIHJldHVybiByZXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXAoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5CeXRlc1dyYXBwZXJTaXplfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLkJ5dGVzV3JhcHBlclNpemUpCiAgICAgICAgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLmludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfQnl0ZXNXcmFwcGVyU2l6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZV9CeXRlc1dyYXBwZXJTaXplX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplLmNsYXNzLCBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAgIG9wdF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgcmVwXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZV9CeXRlc1dyYXBwZXJTaXplX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSBidWlsZCgpIHsKICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzJfdGVzdF9jaGVja191dGY4X3NpemUuVGVzdENoZWNrVXRmOFNpemUuQnl0ZXNXcmFwcGVyU2l6ZSByZXN1bHQgPSBuZXcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxXyA9IHJlcV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0XyA9IG9wdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBfID0gcmVwXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyByZXFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgcmVxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgcmVxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXEoKSB7CiAgICAgICAgcmV0dXJuIHJlcV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcShjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHJlcV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIHJlcSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgcmVxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFJlcSgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHQoKSB7CiAgICAgICAgcmV0dXJuIG9wdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwXyA9IG1ha2VNdXRhYmxlQ29weShyZXBfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXAgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldFJlcExpc3QoKSB7CiAgICAgICAgcmVwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcENvdW50KCkgewogICAgICAgIHJldHVybiByZXBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXAoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcElzTXV0YWJsZSgpOwogICAgICAgIHJlcF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwKCkgewogICAgICAgIHJlcF8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLkJ5dGVzV3JhcHBlclNpemUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5CeXRlc1dyYXBwZXJTaXplKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS5UZXN0Q2hlY2tVdGY4U2l6ZS5CeXRlc1dyYXBwZXJTaXplIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qnl0ZXNXcmFwcGVyU2l6ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxCeXRlc1dyYXBwZXJTaXplPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnl0ZXNXcmFwcGVyU2l6ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJ5dGVzV3JhcHBlclNpemU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qnl0ZXNXcmFwcGVyU2l6ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplLlRlc3RDaGVja1V0ZjhTaXplLkJ5dGVzV3JhcHBlclNpemUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX1N0cmluZ1dyYXBwZXJTaXplX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZV9TdHJpbmdXcmFwcGVyU2l6ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX0J5dGVzV3JhcHBlclNpemVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX0J5dGVzV3JhcHBlclNpemVfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi5jb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfY2hlY2tfdXRmOF9zaSIgKwogICAgICAiemUucHJvdG9cMDIyXDAzM3Byb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZVwiOlxuIiArCiAgICAgICJcMDIxU3RyaW5nV3JhcHBlclNpemVcMDIyXDAxM1xuXDAwM3JlcVwwMzBcMDAxIFwwMDIoXHRcMDIyXDAxM1xuXDAwM29wdFwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcdFwwMjJcMDEzXG5cMDAzcmVwXDAzMFwwMDMgXDAwMyhcdFwiOVxuXDAyMEJ5dGVzV3JhcHBlclNpemVcMDIyXDAxM1xuIiArCiAgICAgICJcMDAzcmVxXDAzMFwwMDEgXDAwMihcMDE0XDAyMlwwMTNcblwwMDNvcHRcMDMwXDAwMiBcMDAxKFwwMTRcMDIyXDAxM1xuXDAwM3JlcFwwMzBcMDAzIFwwMDMoXDAxNEJcMDMwQlwwMjEiICsKICAgICAgIlRlc3RDaGVja1V0ZjhTaXplSFwwMDJcMzMwXDAwMVwwMDEiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfU3RyaW5nV3JhcHBlclNpemVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3Rlc3RfY2hlY2tfdXRmOF9zaXplX1N0cmluZ1dyYXBwZXJTaXplX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZV9TdHJpbmdXcmFwcGVyU2l6ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVxIiwgIk9wdCIsICJSZXAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfQnl0ZXNXcmFwcGVyU2l6ZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfQnl0ZXNXcmFwcGVyU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfdGVzdF9jaGVja191dGY4X3NpemVfQnl0ZXNXcmFwcGVyU2l6ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVxIiwgIk9wdCIsICJSZXAiLCB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAIeqm1urCQAAqwkAACoAAABwcm90b2J1Zl91bml0dGVzdC9DYWNoZWRGaWVsZFNpemVUZXN0LmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvY2FjaGVkX2ZpZWxkX3NpemVfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgQ2FjaGVkRmllbGRTaXplVGVzdCB7CiAgcHJpdmF0ZSBDYWNoZWRGaWVsZFNpemVUZXN0KCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4wY29tL2dvb2dsZS9wcm90b2J1Zi9jYWNoZWRfZmllbGRfc2l6ZV8iICsKICAgICAgInRlc3QucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0XDAzMlwwMzZnb29nbGUvcHIiICsKICAgICAgIm90b2J1Zi91bml0dGVzdC5wcm90b1wwMzIlZ29vZ2xlL3Byb3RvYnVmL3UiICsKICAgICAgIm5pdHRlc3RfcHJvdG8zLnByb3RvXCJcMjE2XDAwMVxuXDAzMlRlc3RDYWNoZWRGaWVsZCIgKwogICAgICAiU2l6ZU1lc3NhZ2VcMDIyOFxuXDAxNHByb3RvMl9jaGlsZFwwMzBcMDAxIFwwMDEoXDAxMzJcIi5wcm90IiArCiAgICAgICJvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlc1wwMjI2XG5cMDE0cHJvdG8zXyIgKwogICAgICAiY2hpbGRcMDMwXDAwMiBcMDAxKFwwMTMyIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZCIgKwogICAgICAiVHlwZXNCXDAwNEhcMDAyUFwwMDEiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUHJvdG8yQ2hpbGQiLCAiUHJvdG8zQ2hpbGQiLCB9KTsKICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpOwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAKvJJJ0HYQAAB2EAAB0AAABwcm90b2J1Zl91bml0dGVzdC9FbmdpbmUuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgovKioKICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lfQogKi8KcHVibGljIGZpbmFsIGNsYXNzIEVuZ2luZSBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkKICAgIEVuZ2luZU9yQnVpbGRlciB7CnByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogIC8vIFVzZSBFbmdpbmUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIEVuZ2luZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgIHN1cGVyKGJ1aWxkZXIpOwogIH0KICBwcml2YXRlIEVuZ2luZSgpIHsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgcmV0dXJuIG5ldyBFbmdpbmUoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkQnVpbGRlcnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VuZ2luZV9kZXNjcmlwdG9yOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkQnVpbGRlcnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VuZ2luZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuQnVpbGRlci5jbGFzcyk7CiAgfQoKICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENZTElOREVSX0ZJRUxEX05VTUJFUiA9IDE7CiAgcHJpdmF0ZSBpbnQgY3lsaW5kZXJfID0gMDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjeWxpbmRlciA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgY3lsaW5kZXIgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNDeWxpbmRlcigpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgY3lsaW5kZXIgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBjeWxpbmRlci4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRDeWxpbmRlcigpIHsKICAgIHJldHVybiBjeWxpbmRlcl87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMSVRFUlNfRklFTERfTlVNQkVSID0gMjsKICBwcml2YXRlIGludCBsaXRlcnNfID0gMDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBsaXRlcnMgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxpdGVycyBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0xpdGVycygpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbGl0ZXJzID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgbGl0ZXJzLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldExpdGVycygpIHsKICAgIHJldHVybiBsaXRlcnNfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVElNSU5HX0JFTFRfRklFTERfTlVNQkVSID0gMzsKICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdGltaW5nQmVsdF87CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdGltaW5nX2JlbHQgPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHRpbWluZ0JlbHQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNUaW1pbmdCZWx0KCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB0aW1pbmdfYmVsdCA9IDM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHRpbWluZ0JlbHQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IGdldFRpbWluZ0JlbHQoKSB7CiAgICByZXR1cm4gdGltaW5nQmVsdF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB0aW1pbmdCZWx0XzsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdGltaW5nX2JlbHQgPSAzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHRPckJ1aWxkZXIgZ2V0VGltaW5nQmVsdE9yQnVpbGRlcigpIHsKICAgIHJldHVybiB0aW1pbmdCZWx0XyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHRpbWluZ0JlbHRfOwogIH0KCiAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgY3lsaW5kZXJfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBsaXRlcnNfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldFRpbWluZ0JlbHQoKSk7CiAgICB9CiAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICBzaXplID0gMDsKICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBjeWxpbmRlcl8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGxpdGVyc18pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0VGltaW5nQmVsdCgpKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkpIHsKICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgfQogICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkgb2JqOwoKICAgIGlmIChoYXNDeWxpbmRlcigpICE9IG90aGVyLmhhc0N5bGluZGVyKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNDeWxpbmRlcigpKSB7CiAgICAgIGlmIChnZXRDeWxpbmRlcigpCiAgICAgICAgICAhPSBvdGhlci5nZXRDeWxpbmRlcigpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzTGl0ZXJzKCkgIT0gb3RoZXIuaGFzTGl0ZXJzKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNMaXRlcnMoKSkgewogICAgICBpZiAoZ2V0TGl0ZXJzKCkKICAgICAgICAgICE9IG90aGVyLmdldExpdGVycygpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzVGltaW5nQmVsdCgpICE9IG90aGVyLmhhc1RpbWluZ0JlbHQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc1RpbWluZ0JlbHQoKSkgewogICAgICBpZiAoIWdldFRpbWluZ0JlbHQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRUaW1pbmdCZWx0KCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICB9CiAgICBpbnQgaGFzaCA9IDQxOwogICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICBpZiAoaGFzQ3lsaW5kZXIoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDWUxJTkRFUl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEN5bGluZGVyKCk7CiAgICB9CiAgICBpZiAoaGFzTGl0ZXJzKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTElURVJTX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TGl0ZXJzKCk7CiAgICB9CiAgICBpZiAoaGFzVGltaW5nQmVsdCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRJTUlOR19CRUxUX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VGltaW5nQmVsdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgcmV0dXJuIGhhc2g7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBwYXJzZUZyb20oCiAgICAgIGJ5dGVbXSBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogIH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgcHJvdG90eXBlKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICB9CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICByZXR1cm4gYnVpbGRlcjsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lT3JCdWlsZGVyIHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbmdpbmVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW5naW5lX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZS5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgfQoKICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBzdXBlcihwYXJlbnQpOwogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CiAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICBnZXRUaW1pbmdCZWx0RmllbGRCdWlsZGVyKCk7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICBzdXBlci5jbGVhcigpOwogICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgY3lsaW5kZXJfID0gMDsKICAgICAgbGl0ZXJzXyA9IDA7CiAgICAgIHRpbWluZ0JlbHRfID0gbnVsbDsKICAgICAgaWYgKHRpbWluZ0JlbHRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgdGltaW5nQmVsdEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICB0aW1pbmdCZWx0QnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbmdpbmVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBidWlsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICB9CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lKHRoaXMpOwogICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICBvbkJ1aWx0KCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5jeWxpbmRlcl8gPSBjeWxpbmRlcl87CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgcmVzdWx0LmxpdGVyc18gPSBsaXRlcnNfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHJlc3VsdC50aW1pbmdCZWx0XyA9IHRpbWluZ0JlbHRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gdGltaW5nQmVsdF8KICAgICAgICAgICAgOiB0aW1pbmdCZWx0QnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkgewogICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSlvdGhlcik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgb3RoZXIpIHsKICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgIGlmIChvdGhlci5oYXNDeWxpbmRlcigpKSB7CiAgICAgICAgc2V0Q3lsaW5kZXIob3RoZXIuZ2V0Q3lsaW5kZXIoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc0xpdGVycygpKSB7CiAgICAgICAgc2V0TGl0ZXJzKG90aGVyLmdldExpdGVycygpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzVGltaW5nQmVsdCgpKSB7CiAgICAgICAgbWVyZ2VUaW1pbmdCZWx0KG90aGVyLmdldFRpbWluZ0JlbHQoKSk7CiAgICAgIH0KICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgY3lsaW5kZXJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgbGl0ZXJzXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0VGltaW5nQmVsdEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gLy8gZmluYWxseQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgcHJpdmF0ZSBpbnQgY3lsaW5kZXJfIDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgY3lsaW5kZXIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY3lsaW5kZXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDeWxpbmRlcigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjeWxpbmRlciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY3lsaW5kZXIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Q3lsaW5kZXIoKSB7CiAgICAgIHJldHVybiBjeWxpbmRlcl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGN5bGluZGVyID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGN5bGluZGVyIHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0Q3lsaW5kZXIoaW50IHZhbHVlKSB7CgogICAgICBjeWxpbmRlcl8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGN5bGluZGVyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ3lsaW5kZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgY3lsaW5kZXJfID0gMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgaW50IGxpdGVyc18gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBsaXRlcnMgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGl0ZXJzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTGl0ZXJzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGxpdGVycyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbGl0ZXJzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldExpdGVycygpIHsKICAgICAgcmV0dXJuIGxpdGVyc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGxpdGVycyA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBsaXRlcnMgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRMaXRlcnMoaW50IHZhbHVlKSB7CgogICAgICBsaXRlcnNfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBsaXRlcnMgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMaXRlcnMoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgbGl0ZXJzXyA9IDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdGltaW5nQmVsdF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCwgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0T3JCdWlsZGVyPiB0aW1pbmdCZWx0QnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHRpbWluZ19iZWx0ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHRpbWluZ0JlbHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNUaW1pbmdCZWx0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHRpbWluZ19iZWx0ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB0aW1pbmdCZWx0LgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBnZXRUaW1pbmdCZWx0KCkgewogICAgICBpZiAodGltaW5nQmVsdEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdGltaW5nQmVsdF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB0aW1pbmdCZWx0XzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdGltaW5nQmVsdEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB0aW1pbmdfYmVsdCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRUaW1pbmdCZWx0KHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdmFsdWUpIHsKICAgICAgaWYgKHRpbWluZ0JlbHRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0aW1pbmdCZWx0XyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIHRpbWluZ0JlbHRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdGltaW5nX2JlbHQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VGltaW5nQmVsdCgKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh0aW1pbmdCZWx0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHRpbWluZ0JlbHRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGltaW5nQmVsdEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB0aW1pbmdfYmVsdCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVRpbWluZ0JlbHQocHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB2YWx1ZSkgewogICAgICBpZiAodGltaW5nQmVsdEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkgJiYKICAgICAgICAgIHRpbWluZ0JlbHRfICE9IG51bGwgJiYKICAgICAgICAgIHRpbWluZ0JlbHRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldFRpbWluZ0JlbHRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGltaW5nQmVsdF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGltaW5nQmVsdEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKHRpbWluZ0JlbHRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHRpbWluZ19iZWx0ID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVGltaW5nQmVsdCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICB0aW1pbmdCZWx0XyA9IG51bGw7CiAgICAgIGlmICh0aW1pbmdCZWx0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHRpbWluZ0JlbHRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgdGltaW5nQmVsdEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHRpbWluZ19iZWx0ID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0LkJ1aWxkZXIgZ2V0VGltaW5nQmVsdEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRUaW1pbmdCZWx0RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB0aW1pbmdfYmVsdCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdE9yQnVpbGRlciBnZXRUaW1pbmdCZWx0T3JCdWlsZGVyKCkgewogICAgICBpZiAodGltaW5nQmVsdEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdGltaW5nQmVsdEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdGltaW5nQmVsdF8gPT0gbnVsbCA/CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB0aW1pbmdCZWx0XzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB0aW1pbmdfYmVsdCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCwgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0T3JCdWlsZGVyPiAKICAgICAgICBnZXRUaW1pbmdCZWx0RmllbGRCdWlsZGVyKCkgewogICAgICBpZiAodGltaW5nQmVsdEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB0aW1pbmdCZWx0QnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCwgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldFRpbWluZ0JlbHQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHRpbWluZ0JlbHRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdGltaW5nQmVsdEJ1aWxkZXJfOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lKCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEVuZ2luZT4KICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RW5naW5lPigpIHsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBFbmdpbmUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxFbmdpbmU+IHBhcnNlcigpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEVuZ2luZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKfQoKUEsDBAoAAAAAAAAAIQC93bcgDQUAAA0FAAAmAAAAcHJvdG9idWZfdW5pdHRlc3QvRW5naW5lT3JCdWlsZGVyLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2J1aWxkZXJzX3Rlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGludGVyZmFjZSBFbmdpbmVPckJ1aWxkZXIgZXh0ZW5kcwogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSkKICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGN5bGluZGVyID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjeWxpbmRlciBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNDeWxpbmRlcigpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGN5bGluZGVyID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgY3lsaW5kZXIuCiAgICovCiAgaW50IGdldEN5bGluZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGxpdGVycyA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGl0ZXJzIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0xpdGVycygpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGxpdGVycyA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGxpdGVycy4KICAgKi8KICBpbnQgZ2V0TGl0ZXJzKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHRpbWluZ19iZWx0ID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0aW1pbmdCZWx0IGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1RpbWluZ0JlbHQoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCB0aW1pbmdfYmVsdCA9IDM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHRpbWluZ0JlbHQuCiAgICovCiAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBnZXRUaW1pbmdCZWx0KCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgdGltaW5nX2JlbHQgPSAzOzwvY29kZT4KICAgKi8KICBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0T3JCdWlsZGVyIGdldFRpbWluZ0JlbHRPckJ1aWxkZXIoKTsKfQpQSwMECgAAAAAAAAAhAI5Ym6YxCwAAMQsAACYAAABwcm90b2J1Zl91bml0dGVzdC9FbnVtV2l0aE5vT3V0ZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCi8qKgogKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXJ9CiAqLwpwdWJsaWMgZW51bSBFbnVtV2l0aE5vT3V0ZXIKICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAvKioKICAgKiA8Y29kZT5GT08gPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmVudW1fdmFsdWVfb3B0aW9uKSA9IDEyMzQ1XTs8L2NvZGU+CiAgICovCiAgRk9PKDEpLAogIC8qKgogICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAqLwogIEJBUigyKSwKICA7CgogIC8qKgogICAqIDxjb2RlPkZPTyA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZW51bV92YWx1ZV9vcHRpb24pID0gMTIzNDVdOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVkFMVUUgPSAxOwogIC8qKgogICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDI7CgoKICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgc3RhdGljIEVudW1XaXRoTm9PdXRlciB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgfQoKICAvKioKICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICovCiAgcHVibGljIHN0YXRpYyBFbnVtV2l0aE5vT3V0ZXIgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgIGNhc2UgMjogcmV0dXJuIEJBUjsKICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICB9CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bVdpdGhOb091dGVyPgogICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgfQogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgIEVudW1XaXRoTm9PdXRlcj4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bVdpdGhOb091dGVyPigpIHsKICAgICAgICAgIHB1YmxpYyBFbnVtV2l0aE5vT3V0ZXIgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICByZXR1cm4gRW51bVdpdGhOb091dGVyLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgfQogICAgICAgIH07CgogIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICB9CiAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogIH0KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFbnVtV2l0aE5vT3V0ZXJbXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgcHVibGljIHN0YXRpYyBFbnVtV2l0aE5vT3V0ZXIgdmFsdWVPZigKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICB9CiAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgfQoKICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgcHJpdmF0ZSBFbnVtV2l0aE5vT3V0ZXIoaW50IHZhbHVlKSB7CiAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIpCn0KClBLAwQKAAAAAAAAACEAVkn1jQQkAgAEJAIAJQAAAHByb3RvYnVmX3VuaXR0ZXN0L0xhenlGaWVsZHNMaXRlLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbGF6eV9maWVsZHNfbGl0ZS5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgTGF6eUZpZWxkc0xpdGUgewogIHByaXZhdGUgTGF6eUZpZWxkc0xpdGUoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbi5leHRlbnNpb24pOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIExhenlNZXNzYWdlTGl0ZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5MYXp5TWVzc2FnZUxpdGUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOdW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBudW0uCiAgICAgKi8KICAgIGludCBnZXROdW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDIxXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bVdpdGhEZWZhdWx0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOdW1XaXRoRGVmYXVsdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDQyMV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbnVtV2l0aERlZmF1bHQuCiAgICAgKi8KICAgIGludCBnZXROdW1XaXRoRGVmYXVsdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5uZXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0lubmVyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lciA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbm5lci4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgZ2V0SW5uZXIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0SW5uZXJPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlPiAKICAgICAgICBnZXRSZXBlYXRlZElubmVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBnZXRSZXBlYXRlZElubmVyKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZElubmVyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZElubmVyT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRSZXBlYXRlZElubmVyT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9udW0gPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOdW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mTnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIG9uZW9mX251bSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOdW0uCiAgICAgKi8KICAgIGludCBnZXRPbmVvZk51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIG9uZW9mX2lubmVyID0gNiBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZJbm5lciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZJbm5lcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgb25lb2ZfaW5uZXIgPSA2IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZJbm5lci4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgZ2V0T25lb2ZJbm5lcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgb25lb2ZfaW5uZXIgPSA2IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXRPbmVvZklubmVyT3JCdWlsZGVyKCk7CgogICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlLk9uZW9mRmllbGRDYXNlIGdldE9uZW9mRmllbGRDYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlNZXNzYWdlTGl0ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIExhenlNZXNzYWdlTGl0ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5MYXp5TWVzc2FnZUxpdGUpCiAgICAgIExhenlNZXNzYWdlTGl0ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTGF6eU1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIExhenlNZXNzYWdlTGl0ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIExhenlNZXNzYWdlTGl0ZSgpIHsKICAgICAgbnVtV2l0aERlZmF1bHRfID0gNDIxOwogICAgICByZXBlYXRlZElubmVyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBMYXp5TWVzc2FnZUxpdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb25lb2ZGaWVsZF87CiAgICBwdWJsaWMgZW51bSBPbmVvZkZpZWxkQ2FzZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2UuSW50ZXJuYWxPbmVPZkVudW0gewogICAgICBPTkVPRl9OVU0oNSksCiAgICAgIE9ORU9GX0lOTkVSKDYpLAogICAgICBPTkVPRkZJRUxEX05PVF9TRVQoMCk7CiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgICBwcml2YXRlIE9uZW9mRmllbGRDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZENhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSA1OiByZXR1cm4gT05FT0ZfTlVNOwogICAgICAgICAgY2FzZSA2OiByZXR1cm4gT05FT0ZfSU5ORVI7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBPTkVPRkZJRUxEX05PVF9TRVQ7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIE9uZW9mRmllbGRDYXNlCiAgICBnZXRPbmVvZkZpZWxkQ2FzZSgpIHsKICAgICAgcmV0dXJuIE9uZW9mRmllbGRDYXNlLmZvck51bWJlcigKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVNX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBudW1fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc051bSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXROdW0oKSB7CiAgICAgIHJldHVybiBudW1fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTV9XSVRIX0RFRkFVTFRfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IG51bVdpdGhEZWZhdWx0XyA9IDQyMTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtX3dpdGhfZGVmYXVsdCA9IDIgW2RlZmF1bHQgPSA0MjFdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNOdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDQyMV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbnVtV2l0aERlZmF1bHQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVtV2l0aERlZmF1bHQoKSB7CiAgICAgIHJldHVybiBudW1XaXRoRGVmYXVsdF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5ORVJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbm5lciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0lubmVyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lciA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbm5lci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIGdldElubmVyKCkgewogICAgICByZXR1cm4gaW5uZXJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGlubmVyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldElubmVyT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gaW5uZXJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGlubmVyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTk5FUl9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlPiByZXBlYXRlZElubmVyXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlPiBnZXRSZXBlYXRlZElubmVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZElubmVyT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW5uZXJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIGdldFJlcGVhdGVkSW5uZXIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZElubmVyXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbm5lck9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfTlVNX0ZJRUxEX05VTUJFUiA9IDU7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIG9uZW9mX251bSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mTnVtKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIG9uZW9mX251bSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOdW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZOdW0oKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX0lOTkVSX0ZJRUxEX05VTUJFUiA9IDY7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBvbmVvZl9pbm5lciA9IDYgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mSW5uZXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZklubmVyKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDY7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBvbmVvZl9pbm5lciA9IDYgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZklubmVyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgZ2V0T25lb2ZJbm5lcigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIG9uZW9mX2lubmVyID0gNiBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldE9uZW9mSW5uZXJPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0lubmVyKCkpIHsKICAgICAgICBpZiAoIWdldElubmVyKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldFJlcGVhdGVkSW5uZXJDb3VudCgpOyBpKyspIHsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkSW5uZXIoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoaGFzT25lb2ZJbm5lcigpKSB7CiAgICAgICAgaWYgKCFnZXRPbmVvZklubmVyKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIG51bVdpdGhEZWZhdWx0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCBnZXRJbm5lcigpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW5uZXJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0LCByZXBlYXRlZElubmVyXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKAogICAgICAgICAgICA1LCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg2LCAocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIG51bVdpdGhEZWZhdWx0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGdldElubmVyKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbm5lcl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgcmVwZWF0ZWRJbm5lcl8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKAogICAgICAgICAgICAgIDUsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDYpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlKSBvYmo7CgogICAgICBpZiAoaGFzTnVtKCkgIT0gb3RoZXIuaGFzTnVtKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc051bSgpKSB7CiAgICAgICAgaWYgKGdldE51bSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE51bSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc051bVdpdGhEZWZhdWx0KCkgIT0gb3RoZXIuaGFzTnVtV2l0aERlZmF1bHQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTnVtV2l0aERlZmF1bHQoKSkgewogICAgICAgIGlmIChnZXROdW1XaXRoRGVmYXVsdCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE51bVdpdGhEZWZhdWx0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW5uZXIoKSAhPSBvdGhlci5oYXNJbm5lcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbm5lcigpKSB7CiAgICAgICAgaWYgKCFnZXRJbm5lcigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW5uZXIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkSW5uZXJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbm5lckxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPbmVvZkZpZWxkQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgNToKICAgICAgICAgIGlmIChnZXRPbmVvZk51bSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T25lb2ZOdW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgaWYgKCFnZXRPbmVvZklubmVyKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9uZW9mSW5uZXIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc051bSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXROdW0oKTsKICAgICAgfQogICAgICBpZiAoaGFzTnVtV2l0aERlZmF1bHQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5VTV9XSVRIX0RFRkFVTFRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE51bVdpdGhEZWZhdWx0KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0lubmVyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTk5FUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW5uZXIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZElubmVyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTk5FUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbm5lckxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIHN3aXRjaCAob25lb2ZGaWVsZENhc2VfKSB7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mTnVtKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9JTk5FUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZklubmVyKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5MYXp5TWVzc2FnZUxpdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5MYXp5TWVzc2FnZUxpdGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5TWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRJbm5lckZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRJbm5lckZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbnVtXyA9IDA7CiAgICAgICAgbnVtV2l0aERlZmF1bHRfID0gNDIxOwogICAgICAgIGlubmVyXyA9IG51bGw7CiAgICAgICAgaWYgKGlubmVyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgaW5uZXJCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBpbm5lckJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZElubmVyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbm5lcl8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpZiAob25lb2ZJbm5lckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9uZW9mSW5uZXJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbm5lcl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZElubmVyXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZElubmVyXyA9IHJlcGVhdGVkSW5uZXJfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbm5lcl8gPSByZXBlYXRlZElubmVyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5udW1fID0gbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5udW1XaXRoRGVmYXVsdF8gPSBudW1XaXRoRGVmYXVsdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW5uZXJfID0gaW5uZXJCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBpbm5lcl8KICAgICAgICAgICAgICA6IGlubmVyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRDYXNlXyA9IG9uZW9mRmllbGRDYXNlXzsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSB0aGlzLm9uZW9mRmllbGRfOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNiAmJgogICAgICAgICAgICBvbmVvZklubmVyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gb25lb2ZJbm5lckJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TWVzc2FnZUxpdGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc051bSgpKSB7CiAgICAgICAgICBzZXROdW0ob3RoZXIuZ2V0TnVtKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTnVtV2l0aERlZmF1bHQoKSkgewogICAgICAgICAgc2V0TnVtV2l0aERlZmF1bHQob3RoZXIuZ2V0TnVtV2l0aERlZmF1bHQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNJbm5lcigpKSB7CiAgICAgICAgICBtZXJnZUlubmVyKG90aGVyLmdldElubmVyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbm5lcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZElubmVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZElubmVyXyA9IG90aGVyLnJlcGVhdGVkSW5uZXJfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZElubmVySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lcl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW5uZXJfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZElubmVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lcl8gPSBvdGhlci5yZXBlYXRlZElubmVyXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lckJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkSW5uZXJGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkSW5uZXJfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKG90aGVyLmdldE9uZW9mRmllbGRDYXNlKCkpIHsKICAgICAgICAgIGNhc2UgT05FT0ZfTlVNOiB7CiAgICAgICAgICAgIHNldE9uZW9mTnVtKG90aGVyLmdldE9uZW9mTnVtKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfSU5ORVI6IHsKICAgICAgICAgICAgbWVyZ2VPbmVvZklubmVyKG90aGVyLmdldE9uZW9mSW5uZXIoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRkZJRUxEX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzSW5uZXIoKSkgewogICAgICAgICAgaWYgKCFnZXRJbm5lcigpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRJbm5lckNvdW50KCk7IGkrKykgewogICAgICAgICAgaWYgKCFnZXRSZXBlYXRlZElubmVyKGkpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChoYXNPbmVvZklubmVyKCkpIHsKICAgICAgICAgIGlmICghZ2V0T25lb2ZJbm5lcigpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBudW1fID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG51bVdpdGhEZWZhdWx0XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0SW5uZXJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW5uZXJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lcl8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9uZW9mSW5uZXJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvbmVvZkZpZWxkXzsKICAgICAgcHVibGljIE9uZW9mRmllbGRDYXNlCiAgICAgICAgICBnZXRPbmVvZkZpZWxkQ2FzZSgpIHsKICAgICAgICByZXR1cm4gT25lb2ZGaWVsZENhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8pOwogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mRmllbGQoKSB7CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBudW1fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc051bSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtKCkgewogICAgICAgIHJldHVybiBudW1fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROdW0oaW50IHZhbHVlKSB7CgogICAgICAgIG51bV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgbnVtXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG51bVdpdGhEZWZhdWx0XyA9IDQyMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDIxXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDIxXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG51bVdpdGhEZWZhdWx0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE51bVdpdGhEZWZhdWx0KCkgewogICAgICAgIHJldHVybiBudW1XaXRoRGVmYXVsdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDIxXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtV2l0aERlZmF1bHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROdW1XaXRoRGVmYXVsdChpbnQgdmFsdWUpIHsKCiAgICAgICAgbnVtV2l0aERlZmF1bHRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDQyMV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bVdpdGhEZWZhdWx0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBudW1XaXRoRGVmYXVsdF8gPSA0MjE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXI+IGlubmVyQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGlubmVyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0lubmVyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW5uZXIuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgZ2V0SW5uZXIoKSB7CiAgICAgICAgaWYgKGlubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGlubmVyXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBpbm5lcl87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBpbm5lckJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lciA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbm5lcihwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChpbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgaW5uZXJfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlubmVyQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldElubmVyKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoaW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpbm5lcl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaW5uZXJCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VJbm5lcihwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChpbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSAmJgogICAgICAgICAgICBpbm5lcl8gIT0gbnVsbCAmJgogICAgICAgICAgICBpbm5lcl8gIT0gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0SW5uZXJCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlubmVyXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpbm5lckJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChpbm5lcl8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbm5lcigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW5uZXJfID0gbnVsbDsKICAgICAgICBpZiAoaW5uZXJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBpbm5lckJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGlubmVyQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIGlubmVyID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyIGdldElubmVyQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldElubmVyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgaW5uZXIgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldElubmVyT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChpbm5lckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBpbm5lckJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGlubmVyXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGlubmVyXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBpbm5lciA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0SW5uZXJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGlubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaW5uZXJCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLCBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldElubmVyKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBpbm5lcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5uZXJCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZT4gcmVwZWF0ZWRJbm5lcl8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW5uZXJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbm5lcl8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZT4ocmVwZWF0ZWRJbm5lcl8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPiByZXBlYXRlZElubmVyQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZT4gZ2V0UmVwZWF0ZWRJbm5lckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbm5lcl8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZElubmVyQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbm5lcl8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIGdldFJlcGVhdGVkSW5uZXIoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbm5lcl8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZElubmVyKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZElubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZElubmVySXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZElubmVyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW5uZXIoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZElubmVySXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZElubmVyXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW5uZXIocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbm5lcklzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbm5lcl8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbm5lcigKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbm5lcklzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbm5lcl8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZElubmVyKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW5uZXJJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW5uZXJfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbm5lckJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW5uZXIoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZElubmVySXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZElubmVyXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW5uZXIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW5uZXJJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW5uZXJfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW5uZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZElubmVyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZElubmVyKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZElubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbm5lcklzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbm5lcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZElubmVyQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBnZXRSZXBlYXRlZElubmVyQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZElubmVyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbm5lck9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZElubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW5uZXJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZElubmVyT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZElubmVyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkSW5uZXJfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSByZXBlYXRlZF9pbm5lciA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBhZGRSZXBlYXRlZElubmVyQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbm5lckZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlcGVhdGVkX2lubmVyID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyIGFkZFJlcGVhdGVkSW5uZXJCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW5uZXJGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVwZWF0ZWRfaW5uZXIgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkSW5uZXJCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbm5lckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRJbm5lckZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkSW5uZXJCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbm5lcl8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRJbm5lcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbm5lckJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgb25lb2ZfbnVtID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOdW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZOdW0oKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA1OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9udW0gPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZOdW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldE9uZW9mTnVtKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9udW0gPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZk51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mTnVtKGludCB2YWx1ZSkgewoKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1OwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9uZW9mX251bSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mTnVtKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPiBvbmVvZklubmVyQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgb25lb2ZfaW5uZXIgPSA2IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mSW5uZXIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZklubmVyKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIG9uZW9mX2lubmVyID0gNiBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZJbm5lci4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIGdldE9uZW9mSW5uZXIoKSB7CiAgICAgICAgaWYgKG9uZW9mSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDYpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgICAgICByZXR1cm4gb25lb2ZJbm5lckJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBvbmVvZl9pbm5lciA9IDYgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZklubmVyKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZJbm5lckJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA2OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgb25lb2ZfaW5uZXIgPSA2IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZJbm5lcigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mSW5uZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mSW5uZXJCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIG9uZW9mX2lubmVyID0gNiBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT25lb2ZJbm5lcihwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSB2YWx1ZSkgewogICAgICAgIGlmIChvbmVvZklubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2ICYmCiAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKChwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSkgb25lb2ZGaWVsZF8pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICAgICAgIG9uZW9mSW5uZXJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb25lb2ZJbm5lckJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA2OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUgb25lb2ZfaW5uZXIgPSA2IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZklubmVyKCkgewogICAgICAgIGlmIChvbmVvZklubmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZklubmVyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBvbmVvZl9pbm5lciA9IDYgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBnZXRPbmVvZklubmVyQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0T25lb2ZJbm5lckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlIG9uZW9mX2lubmVyID0gNiBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIGdldE9uZW9mSW5uZXJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgJiYgKG9uZW9mSW5uZXJCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgICAgcmV0dXJuIG9uZW9mSW5uZXJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBvbmVvZl9pbm5lciA9IDYgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZJbm5lckZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob25lb2ZJbm5lckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKG9uZW9mRmllbGRDYXNlXyA9PSA2KSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZJbm5lckJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlKSBvbmVvZkZpZWxkXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gb25lb2ZJbm5lckJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkxhenlNZXNzYWdlTGl0ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTGF6eU1lc3NhZ2VMaXRlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU1lc3NhZ2VMaXRlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF6eU1lc3NhZ2VMaXRlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPExhenlNZXNzYWdlTGl0ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIExhenlNZXNzYWdlTGl0ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExhenlNZXNzYWdlTGl0ZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMYXp5TWVzc2FnZUxpdGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlNZXNzYWdlTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIExhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPExhenlJbm5lck1lc3NhZ2VMaXRlPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOdW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBudW0uCiAgICAgKi8KICAgIGludCBnZXROdW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc051bVdpdGhEZWZhdWx0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG51bVdpdGhEZWZhdWx0LgogICAgICovCiAgICBpbnQgZ2V0TnVtV2l0aERlZmF1bHQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc05lc3RlZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5lc3RlZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgZ2V0TmVzdGVkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXROZXN0ZWRPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBMYXp5SW5uZXJNZXNzYWdlTGl0ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIExhenlJbm5lck1lc3NhZ2VMaXRlPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUpCiAgICAgIExhenlJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBMYXp5SW5uZXJNZXNzYWdlTGl0ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBMYXp5SW5uZXJNZXNzYWdlTGl0ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTGF6eUlubmVyTWVzc2FnZUxpdGUoKSB7CiAgICAgIG51bVdpdGhEZWZhdWx0XyA9IDQyOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IExhenlJbm5lck1lc3NhZ2VMaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlJbm5lck1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlJbm5lck1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVU1fRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTnVtKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE51bSgpIHsKICAgICAgcmV0dXJuIG51bV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVNX1dJVEhfREVGQVVMVF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgbnVtV2l0aERlZmF1bHRfID0gNDI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNOdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDQyXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBudW1XaXRoRGVmYXVsdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXROdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgcmV0dXJuIG51bVdpdGhEZWZhdWx0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVNURURfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIG5lc3RlZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc05lc3RlZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5lc3RlZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIGdldE5lc3RlZCgpIHsKICAgICAgcmV0dXJuIG5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIG5lc3RlZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXROZXN0ZWRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBuZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGU+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIG51bVdpdGhEZWZhdWx0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCBnZXROZXN0ZWQoKSk7CiAgICAgIH0KICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoNTM2ODcwOTEyLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIG51bVdpdGhEZWZhdWx0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGdldE5lc3RlZCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUpIG9iajsKCiAgICAgIGlmIChoYXNOdW0oKSAhPSBvdGhlci5oYXNOdW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTnVtKCkpIHsKICAgICAgICBpZiAoZ2V0TnVtKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TnVtKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTnVtV2l0aERlZmF1bHQoKSAhPSBvdGhlci5oYXNOdW1XaXRoRGVmYXVsdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNOdW1XaXRoRGVmYXVsdCgpKSB7CiAgICAgICAgaWYgKGdldE51bVdpdGhEZWZhdWx0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TnVtV2l0aERlZmF1bHQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNOZXN0ZWQoKSAhPSBvdGhlci5oYXNOZXN0ZWQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTmVzdGVkKCkpIHsKICAgICAgICBpZiAoIWdldE5lc3RlZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TmVzdGVkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE51bSgpOwogICAgICB9CiAgICAgIGlmIChoYXNOdW1XaXRoRGVmYXVsdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTlVNX1dJVEhfREVGQVVMVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TnVtV2l0aERlZmF1bHQoKTsKICAgICAgfQogICAgICBpZiAoaGFzTmVzdGVkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBORVNURURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5lc3RlZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUlubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlJbm5lck1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE5lc3RlZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbnVtXyA9IDA7CiAgICAgICAgbnVtV2l0aERlZmF1bHRfID0gNDI7CiAgICAgICAgbmVzdGVkXyA9IG51bGw7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG5lc3RlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG5lc3RlZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5SW5uZXJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm51bV8gPSBudW1fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm51bVdpdGhEZWZhdWx0XyA9IG51bVdpdGhEZWZhdWx0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5uZXN0ZWRfID0gbmVzdGVkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gbmVzdGVkXwogICAgICAgICAgICAgIDogbmVzdGVkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNOdW0oKSkgewogICAgICAgICAgc2V0TnVtKG90aGVyLmdldE51bSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc051bVdpdGhEZWZhdWx0KCkpIHsKICAgICAgICAgIHNldE51bVdpdGhEZWZhdWx0KG90aGVyLmdldE51bVdpdGhEZWZhdWx0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTmVzdGVkKCkpIHsKICAgICAgICAgIG1lcmdlTmVzdGVkKG90aGVyLmdldE5lc3RlZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG51bV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgbnVtV2l0aERlZmF1bHRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXROZXN0ZWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG51bV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTnVtKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdW0oKSB7CiAgICAgICAgcmV0dXJuIG51bV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE51bShpbnQgdmFsdWUpIHsKCiAgICAgICAgbnVtXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgbnVtV2l0aERlZmF1bHRfID0gNDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDQyXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNDJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbnVtV2l0aERlZmF1bHQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtV2l0aERlZmF1bHQoKSB7CiAgICAgICAgcmV0dXJuIG51bVdpdGhEZWZhdWx0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtX3dpdGhfZGVmYXVsdCA9IDIgW2RlZmF1bHQgPSA0Ml07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bVdpdGhEZWZhdWx0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TnVtV2l0aERlZmF1bHQoaW50IHZhbHVlKSB7CgogICAgICAgIG51bVdpdGhEZWZhdWx0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtX3dpdGhfZGVmYXVsdCA9IDIgW2RlZmF1bHQgPSA0Ml07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bVdpdGhEZWZhdWx0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBudW1XaXRoRGVmYXVsdF8gPSA0MjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXI+IG5lc3RlZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIG5lc3RlZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmVzdGVkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc05lc3RlZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgZ2V0TmVzdGVkKCkgewogICAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmVzdGVkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBuZXN0ZWRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbmVzdGVkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIG5lc3RlZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROZXN0ZWQocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgdmFsdWUpIHsKICAgICAgICBpZiAobmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBuZXN0ZWRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG5lc3RlZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmVzdGVkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbmVzdGVkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXN0ZWRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTmVzdGVkKHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSAmJgogICAgICAgICAgICBuZXN0ZWRfICE9IG51bGwgJiYKICAgICAgICAgICAgbmVzdGVkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXROZXN0ZWRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5lc3RlZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmVzdGVkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG5lc3RlZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTmVzdGVkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBuZXN0ZWRfID0gbnVsbDsKICAgICAgICBpZiAobmVzdGVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbmVzdGVkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbmVzdGVkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIG5lc3RlZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuQnVpbGRlciBnZXROZXN0ZWRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0TmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgbmVzdGVkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciBnZXROZXN0ZWRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXN0ZWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBuZXN0ZWRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBuZXN0ZWQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE5lc3RlZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAobmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbmVzdGVkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXROZXN0ZWQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG5lc3RlZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmVzdGVkQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lck1lc3NhZ2VMaXRlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlJbm5lck1lc3NhZ2VMaXRlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF6eUlubmVyTWVzc2FnZUxpdGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TGF6eUlubmVyTWVzc2FnZUxpdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBMYXp5SW5uZXJNZXNzYWdlTGl0ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExhenlJbm5lck1lc3NhZ2VMaXRlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExhenlJbm5lck1lc3NhZ2VMaXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5SW5uZXJNZXNzYWdlTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIExhenlFeHRlbnNpb25PckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTGF6eUV4dGVuc2lvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc05hbWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5hbWUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG5hbWUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE5hbWVCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5MYXp5RXh0ZW5zaW9ufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTGF6eUV4dGVuc2lvbiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5MYXp5RXh0ZW5zaW9uKQogICAgICBMYXp5RXh0ZW5zaW9uT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBMYXp5RXh0ZW5zaW9uLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIExhenlFeHRlbnNpb24oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBMYXp5RXh0ZW5zaW9uKCkgewogICAgICBuYW1lXyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IExhenlFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5RXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbmFtZV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc05hbWUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5hbWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbmFtZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbmFtZV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG5hbWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXROYW1lQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbmFtZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG5hbWVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIG5hbWVfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBuYW1lXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uKSBvYmo7CgogICAgICBpZiAoaGFzTmFtZSgpICE9IG90aGVyLmhhc05hbWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTmFtZSgpKSB7CiAgICAgICAgaWYgKCFnZXROYW1lKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXROYW1lKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTmFtZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTkFNRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TmFtZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5MYXp5RXh0ZW5zaW9ufQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTGF6eUV4dGVuc2lvbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5RXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5RXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBuYW1lXyA9ICIiOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24gcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5uYW1lXyA9IG5hbWVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNOYW1lKCkpIHsKICAgICAgICAgIG5hbWVfID0gb3RoZXIubmFtZV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgbmFtZV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbmFtZV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOYW1lKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbmFtZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBuYW1lXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG5hbWVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TmFtZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbmFtZV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG5hbWVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmFtZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG5hbWVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5hbWUoKSB7CiAgICAgICAgbmFtZV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXROYW1lKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBuYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmFtZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBuYW1lXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5MYXp5RXh0ZW5zaW9uKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5MYXp5RXh0ZW5zaW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF6eUV4dGVuc2lvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxMYXp5RXh0ZW5zaW9uPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgTGF6eUV4dGVuc2lvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExhenlFeHRlbnNpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF6eUV4dGVuc2lvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTAwMDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5MYXp5SW5uZXJNZXNzYWdlTGl0ZSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUlubmVyTWVzc2FnZUxpdGUsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbj4gZXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDAsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5RXh0ZW5zaW9uLmNsYXNzLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eUV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIExhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbnVtLgogICAgICovCiAgICBpbnQgZ2V0TnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc051bVdpdGhEZWZhdWx0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbnVtV2l0aERlZmF1bHQuCiAgICAgKi8KICAgIGludCBnZXROdW1XaXRoRGVmYXVsdCgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIExhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlKQogICAgICBMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSgpIHsKICAgICAgbnVtV2l0aERlZmF1bHRfID0gNDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVNX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBudW1fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc051bSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXROdW0oKSB7CiAgICAgIHJldHVybiBudW1fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTV9XSVRIX0RFRkFVTFRfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IG51bVdpdGhEZWZhdWx0XyA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBudW1XaXRoRGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc051bVdpdGhEZWZhdWx0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbnVtV2l0aERlZmF1bHQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TnVtV2l0aERlZmF1bHQoKSB7CiAgICAgIHJldHVybiBudW1XaXRoRGVmYXVsdF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBudW1XaXRoRGVmYXVsdF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgbnVtV2l0aERlZmF1bHRfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUpIG9iajsKCiAgICAgIGlmIChoYXNOdW0oKSAhPSBvdGhlci5oYXNOdW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTnVtKCkpIHsKICAgICAgICBpZiAoZ2V0TnVtKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TnVtKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTnVtV2l0aERlZmF1bHQoKSAhPSBvdGhlci5oYXNOdW1XaXRoRGVmYXVsdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNOdW1XaXRoRGVmYXVsdCgpKSB7CiAgICAgICAgaWYgKGdldE51bVdpdGhEZWZhdWx0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TnVtV2l0aERlZmF1bHQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc051bSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXROdW0oKTsKICAgICAgfQogICAgICBpZiAoaGFzTnVtV2l0aERlZmF1bHQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5VTV9XSVRIX0RFRkFVTFRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE51bVdpdGhEZWZhdWx0KCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBudW1fID0gMDsKICAgICAgICBudW1XaXRoRGVmYXVsdF8gPSA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5udW1fID0gbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5udW1XaXRoRGVmYXVsdF8gPSBudW1XaXRoRGVmYXVsdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNOdW0oKSkgewogICAgICAgICAgc2V0TnVtKG90aGVyLmdldE51bSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc051bVdpdGhEZWZhdWx0KCkpIHsKICAgICAgICAgIHNldE51bVdpdGhEZWZhdWx0KG90aGVyLmdldE51bVdpdGhEZWZhdWx0KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG51bV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgbnVtV2l0aERlZmF1bHRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgbnVtXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOdW0oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE51bSgpIHsKICAgICAgICByZXR1cm4gbnVtXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TnVtKGludCB2YWx1ZSkgewoKICAgICAgICBudW1fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW0gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOdW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG51bV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBudW1XaXRoRGVmYXVsdF8gPSA0OwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtX3dpdGhfZGVmYXVsdCA9IDIgW2RlZmF1bHQgPSA0XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtV2l0aERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBudW1XaXRoRGVmYXVsdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROdW1XaXRoRGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gbnVtV2l0aERlZmF1bHRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1fd2l0aF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9IDRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1XaXRoRGVmYXVsdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE51bVdpdGhEZWZhdWx0KGludCB2YWx1ZSkgewoKICAgICAgICBudW1XaXRoRGVmYXVsdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bV93aXRoX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gNF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bVdpdGhEZWZhdWx0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBudW1XaXRoRGVmYXVsdF8gPSA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LkxhenlGaWVsZHNMaXRlLkxhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5MYXp5RmllbGRzTGl0ZS5MYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPExhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMYXp5TmVzdGVkSW5uZXJNZXNzYWdlTGl0ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTGF6eUZpZWxkc0xpdGUuTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlNZXNzYWdlTGl0ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUlubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUlubmVyTWVzc2FnZUxpdGVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlFeHRlbnNpb25fZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU5lc3RlZElubmVyTWVzc2FnZUxpdGVfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbipjb20vZ29vZ2xlL3Byb3RvYnVmL2xhenlfZmllbGRzX2xpdGUucCIgKwogICAgICAicm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcIlwyNDZcMDAyXG5cMDE3TGF6eU1lc3NhZ2VMIiArCiAgICAgICJpdGVcMDIyXDAxM1xuXDAwM251bVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDM1XG5cMDIwbnVtX3dpdGhfZGVmYXVsdFwwMzBcMDAyIFwwMDEiICsKICAgICAgIihcMDA1OlwwMDM0MjFcMDIyOlxuXDAwNWlubmVyXDAzMFwwMDMgXDAwMShcMDEzMlwnLnByb3RvYnVmX3VuaXR0ZSIgKwogICAgICAic3QuTGF6eUlubmVyTWVzc2FnZUxpdGVCXDAwMihcMDAxXDAyMkNcblwwMTZyZXBlYXRlZF8iICsKICAgICAgImlubmVyXDAzMFwwMDQgXDAwMyhcMDEzMlwnLnByb3RvYnVmX3VuaXR0ZXN0LkxhenlJbm5lIiArCiAgICAgICJyTWVzc2FnZUxpdGVCXDAwMihcMDAxXDAyMlwwMjNcblx0b25lb2ZfbnVtXDAzMFwwMDUgXDAwMShcMDA1SFwwMDBcMDIyQlxuIiArCiAgICAgICJcMDEzb25lb2ZfaW5uZXJcMDMwXDAwNiBcMDAxKFwwMTMyXCcucHJvdG9idWZfdW5pdHRlc3QuTCIgKwogICAgICAiYXp5SW5uZXJNZXNzYWdlTGl0ZUJcMDAyKFwwMDFIXDAwMEJcclxuXDAxM29uZW9mX2ZpZWxkIiArCiAgICAgICJcIlwyMTdcMDAxXG5cMDI0TGF6eUlubmVyTWVzc2FnZUxpdGVcMDIyXDAxM1xuXDAwM251bVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDM0IiArCiAgICAgICJcblwwMjBudW1fd2l0aF9kZWZhdWx0XDAzMFwwMDIgXDAwMShcMDA1OlwwMDI0MlwwMjJBXG5cMDA2bmVzdGVkXDAzMFwwMDMiICsKICAgICAgIiBcMDAxKFwwMTMyLS5wcm90b2J1Zl91bml0dGVzdC5MYXp5TmVzdGVkSW5uZXIiICsKICAgICAgIk1lc3NhZ2VMaXRlQlwwMDIoXDAwMSpcdFwwMTBcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwifFxuXHJMYXp5RXh0ZW5zIiArCiAgICAgICJpb25cMDIyXDAxNFxuXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0Ml1cblx0ZXh0ZW5zaW9uXDAyMlwnLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuTGF6eUlubmVyTWVzc2FnZUxpdGVcMDMwXDM1MFwwMDcgXDAwMShcMDEzMiAiICsKICAgICAgIi5wcm90b2J1Zl91bml0dGVzdC5MYXp5RXh0ZW5zaW9uXCJGXG5cMDMyTGF6eSIgKwogICAgICAiTmVzdGVkSW5uZXJNZXNzYWdlTGl0ZVwwMjJcMDEzXG5cMDAzbnVtXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMzNcblwwMjBuIiArCiAgICAgICJ1bV93aXRoX2RlZmF1bHRcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMTQiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5TWVzc2FnZUxpdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eU1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlNZXNzYWdlTGl0ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTnVtIiwgIk51bVdpdGhEZWZhdWx0IiwgIklubmVyIiwgIlJlcGVhdGVkSW5uZXIiLCAiT25lb2ZOdW0iLCAiT25lb2ZJbm5lciIsICJPbmVvZkZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUlubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUlubmVyTWVzc2FnZUxpdGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUlubmVyTWVzc2FnZUxpdGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk51bSIsICJOdW1XaXRoRGVmYXVsdCIsICJOZXN0ZWQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9MYXp5RXh0ZW5zaW9uX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTGF6eUV4dGVuc2lvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTmFtZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0xhenlOZXN0ZWRJbm5lck1lc3NhZ2VMaXRlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOdW0iLCAiTnVtV2l0aERlZmF1bHQiLCB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhANeHW8fC7wAAwu8AACkAAABwcm90b2J1Zl91bml0dGVzdC9NZXNzYWdlV2l0aE5vT3V0ZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCi8qKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXJ9CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgTWVzc2FnZVdpdGhOb091dGVyIGV4dGVuZHMKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyKQogICAgTWVzc2FnZVdpdGhOb091dGVyT3JCdWlsZGVyIHsKcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgLy8gVXNlIE1lc3NhZ2VXaXRoTm9PdXRlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogIHByaXZhdGUgTWVzc2FnZVdpdGhOb091dGVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgTWVzc2FnZVdpdGhOb091dGVyKCkgewogICAgZm9yZWlnbl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBuZXN0ZWRFbnVtXyA9IDM7CiAgICBmb3JlaWduRW51bV8gPSAxOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IE1lc3NhZ2VXaXRoTm9PdXRlcigpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfZGVzY3JpcHRvcjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk11bHRpcGxlRmlsZXNUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VXaXRoTm9PdXRlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuQnVpbGRlci5jbGFzcyk7CiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkRW51bX0KICAgKi8KICBwdWJsaWMgZW51bSBOZXN0ZWRFbnVtCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEJBWigzKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfVkFMVUUgPSAzOwoKCiAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgIGNhc2UgMzogcmV0dXJuIEJBWjsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+KCkgewogICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkRW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzSSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICovCiAgICBpbnQgZ2V0SSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UpCiAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk11bHRpcGxlRmlsZXNUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VXaXRoTm9PdXRlcl9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTXVsdGlwbGVGaWxlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGlfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgIHJldHVybiBpXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGlfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBpXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzSSgpICE9IG90aGVyLmhhc0koKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSSgpKSB7CiAgICAgICAgaWYgKGdldEkoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNJKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaV8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlfID0gaV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNJKCkpIHsKICAgICAgICAgIHNldEkob3RoZXIuZ2V0SSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgaV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgICAgcmV0dXJuIGlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEkoaW50IHZhbHVlKSB7CgogICAgICAgIGlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVTVEVEX0ZJRUxEX05VTUJFUiA9IDE7CiAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBuZXN0ZWRfOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBuZXN0ZWQgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc05lc3RlZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIG5lc3RlZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG5lc3RlZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIGdldE5lc3RlZCgpIHsKICAgIHJldHVybiBuZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZF87CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBuZXN0ZWQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE5lc3RlZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBuZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX0ZJRUxEX05VTUJFUiA9IDI7CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZm9yZWlnbl87CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0Rm9yZWlnbkxpc3QoKSB7CiAgICByZXR1cm4gZm9yZWlnbl87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgZ2V0Rm9yZWlnbk9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gZm9yZWlnbl87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldEZvcmVpZ25Db3VudCgpIHsKICAgIHJldHVybiBmb3JlaWduXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0Rm9yZWlnbihpbnQgaW5kZXgpIHsKICAgIHJldHVybiBmb3JlaWduXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEZvcmVpZ25PckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIGZvcmVpZ25fLmdldChpbmRleCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAzOwogIHByaXZhdGUgaW50IG5lc3RlZEVudW1fID0gMzsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZEVudW0gZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzTmVzdGVkRW51bSgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgbmVzdGVkRW51bS4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkRW51bSBnZXROZXN0ZWRFbnVtKCkgewogICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0uZm9yTnVtYmVyKG5lc3RlZEVudW1fKTsKICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtLkJBWiA6IHJlc3VsdDsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVIgPSA0OwogIHByaXZhdGUgaW50IGZvcmVpZ25FbnVtXyA9IDE7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciBmb3JlaWduX2VudW0gPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvcmVpZ25FbnVtIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0ZvcmVpZ25FbnVtKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVdpdGhOb091dGVyIGZvcmVpZ25fZW51bSA9IDQ7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGZvcmVpZ25FbnVtLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciBnZXRGb3JlaWduRW51bSgpIHsKICAgIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIuZm9yTnVtYmVyKGZvcmVpZ25FbnVtXyk7CiAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIuRk9PIDogcmVzdWx0OwogIH0KCiAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXROZXN0ZWQoKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZvcmVpZ25fLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZm9yZWlnbl8uZ2V0KGkpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVFbnVtKDMsIG5lc3RlZEVudW1fKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVFbnVtKDQsIGZvcmVpZ25FbnVtXyk7CiAgICB9CiAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICBzaXplID0gMDsKICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldE5lc3RlZCgpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9yZWlnbl8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBmb3JlaWduXy5nZXQoaSkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlRW51bVNpemUoMywgbmVzdGVkRW51bV8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlRW51bVNpemUoNCwgZm9yZWlnbkVudW1fKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlcikpIHsKICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgfQogICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlcikgb2JqOwoKICAgIGlmIChoYXNOZXN0ZWQoKSAhPSBvdGhlci5oYXNOZXN0ZWQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc05lc3RlZCgpKSB7CiAgICAgIGlmICghZ2V0TmVzdGVkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TmVzdGVkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoIWdldEZvcmVpZ25MaXN0KCkKICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvcmVpZ25MaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzTmVzdGVkRW51bSgpICE9IG90aGVyLmhhc05lc3RlZEVudW0oKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc05lc3RlZEVudW0oKSkgewogICAgICBpZiAobmVzdGVkRW51bV8gIT0gb3RoZXIubmVzdGVkRW51bV8pIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNGb3JlaWduRW51bSgpICE9IG90aGVyLmhhc0ZvcmVpZ25FbnVtKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNGb3JlaWduRW51bSgpKSB7CiAgICAgIGlmIChmb3JlaWduRW51bV8gIT0gb3RoZXIuZm9yZWlnbkVudW1fKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICB9CiAgICBpbnQgaGFzaCA9IDQxOwogICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICBpZiAoaGFzTmVzdGVkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTkVTVEVEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TmVzdGVkKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChnZXRGb3JlaWduQ291bnQoKSA+IDApIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9SRUlHTl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvcmVpZ25MaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChoYXNOZXN0ZWRFbnVtKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBuZXN0ZWRFbnVtXzsKICAgIH0KICAgIGlmIChoYXNGb3JlaWduRW51bSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGZvcmVpZ25FbnVtXzsKICAgIH0KICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICByZXR1cm4gaGFzaDsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHBhcnNlRnJvbSgKICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciBwcm90b3R5cGUpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogIH0KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgIHJldHVybiBidWlsZGVyOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXJ9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyKQogICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXJPckJ1aWxkZXIgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTXVsdGlwbGVGaWxlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTXVsdGlwbGVGaWxlc1Rlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgfQoKICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBzdXBlcihwYXJlbnQpOwogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CiAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICBnZXROZXN0ZWRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXRGb3JlaWduRmllbGRCdWlsZGVyKCk7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICBzdXBlci5jbGVhcigpOwogICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgbmVzdGVkXyA9IG51bGw7CiAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgbmVzdGVkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIG5lc3RlZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBmb3JlaWduXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmb3JlaWduXyA9IG51bGw7CiAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICBuZXN0ZWRFbnVtXyA9IDM7CiAgICAgIGZvcmVpZ25FbnVtXyA9IDE7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk11bHRpcGxlRmlsZXNUZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VXaXRoTm9PdXRlcl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIGJ1aWxkKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIodGhpcyk7CiAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHJlc3VsdCkgewogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIGZvcmVpZ25fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZm9yZWlnbl8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIH0KICAgICAgICByZXN1bHQuZm9yZWlnbl8gPSBmb3JlaWduXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQuZm9yZWlnbl8gPSBmb3JlaWduQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciByZXN1bHQpIHsKICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICByZXN1bHQubmVzdGVkXyA9IG5lc3RlZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBuZXN0ZWRfCiAgICAgICAgICAgIDogbmVzdGVkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQubmVzdGVkRW51bV8gPSBuZXN0ZWRFbnVtXzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQuZm9yZWlnbkVudW1fID0gZm9yZWlnbkVudW1fOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyKW90aGVyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICB9CgogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciBvdGhlcikgewogICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgaWYgKG90aGVyLmhhc05lc3RlZCgpKSB7CiAgICAgICAgbWVyZ2VOZXN0ZWQob3RoZXIuZ2V0TmVzdGVkKCkpOwogICAgICB9CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuZm9yZWlnbl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZm9yZWlnbl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZvcmVpZ25fID0gb3RoZXIuZm9yZWlnbl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZvcmVpZ25Jc011dGFibGUoKTsKICAgICAgICAgICAgZm9yZWlnbl8uYWRkQWxsKG90aGVyLmZvcmVpZ25fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmZvcmVpZ25fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZvcmVpZ25CdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgZm9yZWlnbkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgZm9yZWlnbl8gPSBvdGhlci5mb3JlaWduXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICBmb3JlaWduQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXRGb3JlaWduRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmZvcmVpZ25fKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc05lc3RlZEVudW0oKSkgewogICAgICAgIHNldE5lc3RlZEVudW0ob3RoZXIuZ2V0TmVzdGVkRW51bSgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzRm9yZWlnbkVudW0oKSkgewogICAgICAgIHNldEZvcmVpZ25FbnVtKG90aGVyLmdldEZvcmVpZ25FbnVtKCkpOwogICAgICB9CiAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgdHJ5IHsKICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0TmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUZvcmVpZ25Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZvcmVpZ25fLmFkZChtKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDMsIHRtcFJhdyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5lc3RlZEVudW1fID0gdG1wUmF3OwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDQsIHRtcFJhdyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZvcmVpZ25FbnVtXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IC8vIGZpbmFsbHkKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG5lc3RlZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc05lc3RlZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBnZXROZXN0ZWQoKSB7CiAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbmVzdGVkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBuZXN0ZWQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0TmVzdGVkKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBuZXN0ZWRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbmVzdGVkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBuZXN0ZWQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0TmVzdGVkKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgbmVzdGVkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIG5lc3RlZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTmVzdGVkKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICBuZXN0ZWRfICE9IG51bGwgJiYKICAgICAgICAgIG5lc3RlZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldE5lc3RlZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXN0ZWRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIG5lc3RlZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKG5lc3RlZF8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIG5lc3RlZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5lc3RlZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICBuZXN0ZWRfID0gbnVsbDsKICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBuZXN0ZWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgbmVzdGVkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIG5lc3RlZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXROZXN0ZWRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0TmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXROZXN0ZWRPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbmVzdGVkXyA9PSBudWxsID8KICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBuZXN0ZWRfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBuZXN0ZWQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0TmVzdGVkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAobmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG5lc3RlZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXROZXN0ZWQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG5lc3RlZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBuZXN0ZWRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBmb3JlaWduXyA9CiAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHByaXZhdGUgdm9pZCBlbnN1cmVGb3JlaWduSXNNdXRhYmxlKCkgewogICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgZm9yZWlnbl8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4oZm9yZWlnbl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGZvcmVpZ25CdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldEZvcmVpZ25MaXN0KCkgewogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZm9yZWlnbl8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmb3JlaWduQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGb3JlaWduQ291bnQoKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmb3JlaWduXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGZvcmVpZ25CdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0Rm9yZWlnbihpbnQgaW5kZXgpIHsKICAgICAgaWYgKGZvcmVpZ25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZvcmVpZ25fLmdldChpbmRleCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGZvcmVpZ25CdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9yZWlnbigKICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRm9yZWlnbklzTXV0YWJsZSgpOwogICAgICAgIGZvcmVpZ25fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZvcmVpZ25CdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGb3JlaWduKAogICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZvcmVpZ25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRm9yZWlnbklzTXV0YWJsZSgpOwogICAgICAgIGZvcmVpZ25fLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZvcmVpZ25CdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRGb3JlaWduKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRm9yZWlnbklzTXV0YWJsZSgpOwogICAgICAgIGZvcmVpZ25fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRm9yZWlnbigKICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRm9yZWlnbklzTXV0YWJsZSgpOwogICAgICAgIGZvcmVpZ25fLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZvcmVpZ25CdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRGb3JlaWduKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZvcmVpZ25Jc011dGFibGUoKTsKICAgICAgICBmb3JlaWduXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZvcmVpZ25CdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZvcmVpZ24oCiAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVGb3JlaWduSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yZWlnbl8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZvcmVpZ24oCiAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZvcmVpZ25Jc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZm9yZWlnbl8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZvcmVpZ25CdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb3JlaWduKCkgewogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBmb3JlaWduXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9yZWlnbkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGb3JlaWduKGludCBpbmRleCkgewogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVGb3JlaWduSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yZWlnbl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmb3JlaWduQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldEZvcmVpZ25CdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0Rm9yZWlnbkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEZvcmVpZ25PckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmb3JlaWduXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZm9yZWlnbkJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgZ2V0Rm9yZWlnbk9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmIChmb3JlaWduQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBmb3JlaWduQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZm9yZWlnbl8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRGb3JlaWduQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldEZvcmVpZ25GaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkRm9yZWlnbkJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRGb3JlaWduRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgIGdldEZvcmVpZ25CdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGdldEZvcmVpZ25GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRGb3JlaWduRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoZm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBmb3JlaWduQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZm9yZWlnbl8sCiAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGZvcmVpZ25fID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gZm9yZWlnbkJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgaW50IG5lc3RlZEVudW1fID0gMzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc05lc3RlZEVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gZ2V0TmVzdGVkRW51bSgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0uZm9yTnVtYmVyKG5lc3RlZEVudW1fKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0uQkFaIDogcmVzdWx0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbmVzdGVkRW51bSB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE5lc3RlZEVudW0ocHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIG5lc3RlZEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTmVzdGVkRW51bSgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICBuZXN0ZWRFbnVtXyA9IDM7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGludCBmb3JlaWduRW51bV8gPSAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVdpdGhOb091dGVyIGZvcmVpZ25fZW51bSA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb3JlaWduRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRm9yZWlnbkVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciBmb3JlaWduX2VudW0gPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuRW51bVdpdGhOb091dGVyIGdldEZvcmVpZ25FbnVtKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuRW51bVdpdGhOb091dGVyLmZvck51bWJlcihmb3JlaWduRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIuRk9PIDogcmVzdWx0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVdpdGhOb091dGVyIGZvcmVpZ25fZW51bSA9IDQ7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb3JlaWduRW51bSB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvcmVpZ25FbnVtKHByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciB2YWx1ZSkgewogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgZm9yZWlnbkVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciBmb3JlaWduX2VudW0gPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb3JlaWduRW51bSgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICBmb3JlaWduRW51bV8gPSAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyKQogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlcikKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCiAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVdpdGhOb091dGVyPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlV2l0aE5vT3V0ZXI+KCkgewogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIE1lc3NhZ2VXaXRoTm9PdXRlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgIHRyeSB7CiAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfQogICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgIH0KICB9OwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VXaXRoTm9PdXRlcj4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVdpdGhOb091dGVyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9Cgp9CgpQSwMECgAAAAAAAAAhACaLeq2mCQAApgkAADIAAABwcm90b2J1Zl91bml0dGVzdC9NZXNzYWdlV2l0aE5vT3V0ZXJPckJ1aWxkZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZVdpdGhOb091dGVyT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIpCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzTmVzdGVkKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlIG5lc3RlZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG5lc3RlZC4KICAgKi8KICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuTmVzdGVkTWVzc2FnZSBnZXROZXN0ZWQoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2UgbmVzdGVkID0gMTs8L2NvZGU+CiAgICovCiAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0TmVzdGVkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiAKICAgICAgZ2V0Rm9yZWlnbkxpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvcmVpZ24gPSAyOzwvY29kZT4KICAgKi8KICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGb3JlaWduKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjs8L2NvZGU+CiAgICovCiAgaW50IGdldEZvcmVpZ25Db3VudCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9yZWlnbiA9IDI7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgIGdldEZvcmVpZ25PckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb3JlaWduID0gMjs8L2NvZGU+CiAgICovCiAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Rm9yZWlnbk9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIG5lc3RlZF9lbnVtID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc05lc3RlZEVudW0oKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyLk5lc3RlZEVudW0gbmVzdGVkX2VudW0gPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRFbnVtLgogICAqLwogIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtIGdldE5lc3RlZEVudW0oKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciBmb3JlaWduX2VudW0gPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvcmVpZ25FbnVtIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0ZvcmVpZ25FbnVtKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1XaXRoTm9PdXRlciBmb3JlaWduX2VudW0gPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBmb3JlaWduRW51bS4KICAgKi8KICBwcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3V0ZXIgZ2V0Rm9yZWlnbkVudW0oKTsKfQpQSwMECgAAAAAAAAAhAPOsNazuFQAA7hUAAC0AAABwcm90b2J1Zl91bml0dGVzdC9NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbXVsdGlwbGVfZmlsZXNfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgTXVsdGlwbGVGaWxlc1Rlc3RQcm90byB7CiAgcHJpdmF0ZSBNdWx0aXBsZUZpbGVzVGVzdFByb3RvKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0Lk11bHRpcGxlRmlsZXNUZXN0UHJvdG8uZW51bVZhbHVlT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmV4dGVuc2lvbldpdGhPdXRlcik7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fVkFMVUVfT1BUSU9OX0ZJRUxEX05VTUJFUiA9IDc2NTQzMjE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5FbnVtVmFsdWVPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bVZhbHVlT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWFRFTlNJT05fV0lUSF9PVVRFUl9GSUVMRF9OVU1CRVIgPSAxMjM0NTY3OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZXh0ZW5zaW9uV2l0aE91dGVyID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi1jb20vZ29vZ2xlL3Byb3RvYnVmL211bHRpcGxlX2ZpbGVzX3RlcyIgKwogICAgICAidC5wcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyIGdvb2dsZS9wcm90byIgKwogICAgICAiYnVmL2Rlc2NyaXB0b3IucHJvdG9cMDMyXDAzNmdvb2dsZS9wcm90b2J1Zi91biIgKwogICAgICAiaXR0ZXN0LnByb3RvXCJcMjc3XDAwMlxuXDAyMk1lc3NhZ2VXaXRoTm9PdXRlclwwMjJDXG5cMDA2biIgKwogICAgICAiZXN0ZWRcMDMwXDAwMSBcMDAxKFwwMTMyMy5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlVyIgKwogICAgICAiaXRoTm9PdXRlci5OZXN0ZWRNZXNzYWdlXDAyMjBcblwwMDdmb3JlaWduXDAzMFwwMDIgXDAwMygiICsKICAgICAgIlwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcMDIyRVxuXDAxM25lIiArCiAgICAgICJzdGVkX2VudW1cMDMwXDAwMyBcMDAxKFwwMTYyMC5wcm90b2J1Zl91bml0dGVzdC5NZXNzIiArCiAgICAgICJhZ2VXaXRoTm9PdXRlci5OZXN0ZWRFbnVtXDAyMjhcblwwMTRmb3JlaWduX2VudSIgKwogICAgICAibVwwMzBcMDA0IFwwMDEoXDAxNjJcIi5wcm90b2J1Zl91bml0dGVzdC5FbnVtV2l0aE5vT3UiICsKICAgICAgInRlclwwMzJcMDMyXG5cck5lc3RlZE1lc3NhZ2VcMDIyXHRcblwwMDFpXDAzMFwwMDEgXDAwMShcMDA1XCJcMDI1XG5cbk5lc3RlIiArCiAgICAgICJkRW51bVwwMjJcMDA3XG5cMDAzQkFaXDAyMFwwMDMqK1xuXDAxN0VudW1XaXRoTm9PdXRlclwwMjJcMDE3XG5cMDAzRk9PIiArCiAgICAgICJcMDIwXDAwMVwwMzJcMDA2XDIxMFwyNzNcMjMxXDAzNVwyNzFgXDAyMlwwMDdcblwwMDNCQVJcMDIwXDAwMjJjXG5cMDIyU2VydmljZVdpdGhOb091dGUiICsKICAgICAgInJcMDIyTVxuXDAwM0Zvb1wwMjIlLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoIiArCiAgICAgICJOb091dGVyXDAzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIiArCiAgICAgICI6P1xuXDAyMWVudW1fdmFsdWVfb3B0aW9uXDAyMiEuZ29vZ2xlLnByb3RvYnVmLiIgKwogICAgICAiRW51bVZhbHVlT3B0aW9uc1wwMzBcMjYxXDIyN1wzMjNcMDAzIFwwMDEoXDAwNTpEXG5cMDI0ZXh0ZW5zaW9uX3ciICsKICAgICAgIml0aF9vdXRlclwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHQiICsKICAgICAgImVuc2lvbnNcMDMwXDIwN1wyNTVLIFwwMDEoXDAwNUJcMDM1QlwwMjZNdWx0aXBsZUZpbGVzVGVzdFByb3QiICsKICAgICAgIm9QXDAwMVwyMTBcMDAxXDAwMSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLmdldERlc2NyaXB0b3IoKSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VXaXRoTm9PdXRlcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOZXN0ZWQiLCAiRm9yZWlnbiIsICJOZXN0ZWRFbnVtIiwgIkZvcmVpZ25FbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVdpdGhOb091dGVyX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlV2l0aE5vT3V0ZXJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSSIsIH0pOwogICAgZW51bVZhbHVlT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkpOwogICAgZXh0ZW5zaW9uV2l0aE91dGVyLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMSkpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeS5uZXdJbnN0YW5jZSgpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0Lk11bHRpcGxlRmlsZXNUZXN0UHJvdG8uZW51bVZhbHVlT3B0aW9uKTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgICAuaW50ZXJuYWxVcGRhdGVGaWxlRGVzY3JpcHRvcihkZXNjcmlwdG9yLCByZWdpc3RyeSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuZ2V0RGVzY3JpcHRvcigpOwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQCrvrz9hhAAAIYQAAAlAAAAcHJvdG9idWZfdW5pdHRlc3QvTmVzdGVkQnVpbGRlcnMuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgTmVzdGVkQnVpbGRlcnMgewogIHByaXZhdGUgTmVzdGVkQnVpbGRlcnMoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WZWhpY2xlX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WZWhpY2xlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW5naW5lX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbmdpbmVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UaW1pbmdCZWx0X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UaW1pbmdCZWx0X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1doZWVsX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4uY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGUiICsKICAgICAgInN0LnByb3RvXDAyMlwwMjFwcm90b2J1Zl91bml0dGVzdFwiXVxuXDAwN1ZlaGljbGVcMDIyKSIgKwogICAgICAiXG5cMDA2ZW5naW5lXDAzMFwwMDEgXDAwMShcMDEzMlwwMzEucHJvdG9idWZfdW5pdHRlc3QuRW5naW4iICsKICAgICAgImVcMDIyXCdcblwwMDV3aGVlbFwwMzBcMDAyIFwwMDMoXDAxMzJcMDMwLnByb3RvYnVmX3VuaXR0ZXN0LldoZSIgKwogICAgICAiZWxcIl5cblwwMDZFbmdpbmVcMDIyXDAyMFxuXDAxMGN5bGluZGVyXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMTZcblwwMDZsaXRlcnMiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAwNVwwMjIyXG5cMDEzdGltaW5nX2JlbHRcMDMwXDAwMyBcMDAxKFwwMTMyXDAzNS5wcm90b2J1Zl91IiArCiAgICAgICJuaXR0ZXN0LlRpbWluZ0JlbHRcIiVcblxuVGltaW5nQmVsdFwwMjJcMDI3XG5cMDE3bnVtYiIgKwogICAgICAiZXJfb2ZfdGVldGhcMDMwXDAwMSBcMDAxKFwwMDVcIiZcblwwMDVXaGVlbFwwMjJcMDE2XG5cMDA2cmFkaXVzXDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMDVcMDIyXHJcblwwMDV3aWR0aFwwMzBcMDAyIFwwMDEoXDAwNUJcMDIyQlwwMTZOZXN0ZWRCdWlsZGVyc1BcMDAxIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmVoaWNsZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WZWhpY2xlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1ZlaGljbGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkVuZ2luZSIsICJXaGVlbCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VuZ2luZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbmdpbmVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW5naW5lX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDeWxpbmRlciIsICJMaXRlcnMiLCAiVGltaW5nQmVsdCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RpbWluZ0JlbHRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGltaW5nQmVsdF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UaW1pbmdCZWx0X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOdW1iZXJPZlRlZXRoIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJhZGl1cyIsICJXaWR0aCIsIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEArEU3kCJKAAAiSgAAJgAAAHByb3RvYnVmX3VuaXR0ZXN0L05lc3RlZEV4dGVuc2lvbi5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9leHRlbnNpb24ucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIE5lc3RlZEV4dGVuc2lvbiB7CiAgcHJpdmF0ZSBOZXN0ZWRFeHRlbnNpb24oKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLnJlY3Vyc2l2ZUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLmRlZmF1bHRfKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBNeU5lc3RlZEV4dGVuc2lvbk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTXlOZXN0ZWRFeHRlbnNpb259CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNeU5lc3RlZEV4dGVuc2lvbiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbikKICAgICAgTXlOZXN0ZWRFeHRlbnNpb25PckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE15TmVzdGVkRXh0ZW5zaW9uLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE15TmVzdGVkRXh0ZW5zaW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTXlOZXN0ZWRFeHRlbnNpb24oKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTXlOZXN0ZWRFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015TmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbikgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24gcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTXlOZXN0ZWRFeHRlbnNpb259CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb25PckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015TmVzdGVkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24gYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24gcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbih0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk15TmVzdGVkRXh0ZW5zaW9uKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbi5NeU5lc3RlZEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15TmVzdGVkRXh0ZW5zaW9uPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE15TmVzdGVkRXh0ZW5zaW9uPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgTXlOZXN0ZWRFeHRlbnNpb24gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNeU5lc3RlZEV4dGVuc2lvbj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNeU5lc3RlZEV4dGVuc2lvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQ1VSU0lWRUVYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VUb0JlRXh0ZW5kZWQgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkPiByZWN1cnNpdmVFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb24uTXlOZXN0ZWRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0ZJRUxEX05VTUJFUiA9IDIwMDI7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlZCB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQsCiAgICAgICAgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uLk15TmVzdGVkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuKmNvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2V4dGVuc2lvbi5wIiArCiAgICAgICJyb3RvXDAyMlwwMjFwcm90b2J1Zl91bml0dGVzdFwwMzIuY29tL2dvb2dsZS9wcm90IiArCiAgICAgICJvYnVmL25vbl9uZXN0ZWRfZXh0ZW5zaW9uLnByb3RvXCJcMjcxXDAwMVxuXDAyMU15TmUiICsKICAgICAgInN0ZWRFeHRlbnNpb24yalxuXDAyMnJlY3Vyc2l2ZUV4dGVuc2lvblwwMjImLnByIiArCiAgICAgICJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlZFwwMzBcMDAyIFwwMDEoIiArCiAgICAgICJcMDEzMiYucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlIiArCiAgICAgICJkMjhcblwwMDdkZWZhdWx0XDAyMiYucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZSIgKwogICAgICAiVG9CZUV4dGVuZGVkXDAzMFwzMjJcMDE3IFwwMDEoXDAwNSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQCwQa1hdEwAAHRMAAAqAAAAcHJvdG9idWZfdW5pdHRlc3QvTmVzdGVkRXh0ZW5zaW9uTGl0ZS5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9leHRlbnNpb25fbGl0ZS5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgTmVzdGVkRXh0ZW5zaW9uTGl0ZSB7CiAgcHJpdmF0ZSBOZXN0ZWRFeHRlbnNpb25MaXRlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlLnJlY3Vyc2l2ZUV4dGVuc2lvbkxpdGUpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlLnByaXZhdGVfKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBNeU5lc3RlZEV4dGVuc2lvbkxpdGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTXlOZXN0ZWRFeHRlbnNpb25MaXRlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbkxpdGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNeU5lc3RlZEV4dGVuc2lvbkxpdGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTXlOZXN0ZWRFeHRlbnNpb25MaXRlKQogICAgICBNeU5lc3RlZEV4dGVuc2lvbkxpdGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE15TmVzdGVkRXh0ZW5zaW9uTGl0ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNeU5lc3RlZEV4dGVuc2lvbkxpdGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNeU5lc3RlZEV4dGVuc2lvbkxpdGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTXlOZXN0ZWRFeHRlbnNpb25MaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOZXN0ZWRFeHRlbnNpb25MaXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOZXN0ZWRFeHRlbnNpb25MaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbkxpdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbkxpdGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOZXN0ZWRFeHRlbnNpb25MaXRlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015TmVzdGVkRXh0ZW5zaW9uTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015TmVzdGVkRXh0ZW5zaW9uTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5lc3RlZEV4dGVuc2lvbkxpdGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NeU5lc3RlZEV4dGVuc2lvbkxpdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15TmVzdGVkRXh0ZW5zaW9uTGl0ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNeU5lc3RlZEV4dGVuc2lvbkxpdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBNeU5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNeU5lc3RlZEV4dGVuc2lvbkxpdGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TXlOZXN0ZWRFeHRlbnNpb25MaXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRFeHRlbnNpb25MaXRlLk15TmVzdGVkRXh0ZW5zaW9uTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRUNVUlNJVkVFWFRFTlNJT05MSVRFX0ZJRUxEX05VTUJFUiA9IDM7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZD4gcmVjdXJzaXZlRXh0ZW5zaW9uTGl0ZSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSVZBVEVfRklFTERfTlVNQkVSID0gMjAwNDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCwKICAgICAgICBqYXZhLmxhbmcuRG91YmxlPiBwcml2YXRlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOZXN0ZWRFeHRlbnNpb25MaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015TmVzdGVkRXh0ZW5zaW9uTGl0ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbkxpdGVfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi9jb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9leHRlbnNpb25fbCIgKwogICAgICAiaXRlLnByb3RvXDAyMlwwMjFwcm90b2J1Zl91bml0dGVzdFwwMzIzY29tL2dvb2dsZSIgKwogICAgICAiL3Byb3RvYnVmL25vbl9uZXN0ZWRfZXh0ZW5zaW9uX2xpdGUucHJvdCIgKwogICAgICAib1wiXDMxNVwwMDFcblwwMjVNeU5lc3RlZEV4dGVuc2lvbkxpdGUydlxuXDAyNnJlY3Vyc2l2ZSIgKwogICAgICAiRXh0ZW5zaW9uTGl0ZVwwMjIqLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZyIgKwogICAgICAiZUxpdGVUb0JlRXh0ZW5kZWRcMDMwXDAwMyBcMDAxKFwwMTMyKi5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0Lk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkMjxcblwwMDdwcml2YXRlXDAyMioiICsKICAgICAgIi5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmQiICsKICAgICAgImVkXDAzMFwzMjRcMDE3IFwwMDEoXDAwMUJcMDAySFwwMDMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015TmVzdGVkRXh0ZW5zaW9uTGl0ZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5lc3RlZEV4dGVuc2lvbkxpdGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOZXN0ZWRFeHRlbnNpb25MaXRlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQCQvoAr3JEAANyRAAApAAAAcHJvdG9idWZfdW5pdHRlc3QvTm9uTmVzdGVkRXh0ZW5zaW9uLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbm9uX25lc3RlZF9leHRlbnNpb24ucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIE5vbk5lc3RlZEV4dGVuc2lvbiB7CiAgcHJpdmF0ZSBOb25OZXN0ZWRFeHRlbnNpb24oKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLm5vbk5lc3RlZEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLmlmXyk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZVRvQmVFeHRlbmRlZE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlVG9CZUV4dGVuZGVkKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPE1lc3NhZ2VUb0JlRXh0ZW5kZWQ+IHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VUb0JlRXh0ZW5kZWQgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBNZXNzYWdlVG9CZUV4dGVuZGVkPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlZCkKICAgICAgTWVzc2FnZVRvQmVFeHRlbmRlZE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTWVzc2FnZVRvQmVFeHRlbmRlZC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNZXNzYWdlVG9CZUV4dGVuZGVkKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNZXNzYWdlVG9CZUV4dGVuZGVkKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE1lc3NhZ2VUb0JlRXh0ZW5kZWQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VUb0JlRXh0ZW5kZWRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VUb0JlRXh0ZW5kZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQ+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VUb0JlRXh0ZW5kZWR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlZCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VUb0JlRXh0ZW5kZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlVG9CZUV4dGVuZGVkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlVG9CZUV4dGVuZGVkX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCwgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VUb0JlRXh0ZW5kZWQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VUb0JlRXh0ZW5kZWQpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlVG9CZUV4dGVuZGVkPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE1lc3NhZ2VUb0JlRXh0ZW5kZWQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBNZXNzYWdlVG9CZUV4dGVuZGVkIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZVRvQmVFeHRlbmRlZD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlVG9CZUV4dGVuZGVkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTWVzc2FnZVRvQmVFeHRlbmRlZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE15Tm9uTmVzdGVkRXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0Lk15Tm9uTmVzdGVkRXh0ZW5zaW9uKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NeU5vbk5lc3RlZEV4dGVuc2lvbn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE15Tm9uTmVzdGVkRXh0ZW5zaW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk15Tm9uTmVzdGVkRXh0ZW5zaW9uKQogICAgICBNeU5vbk5lc3RlZEV4dGVuc2lvbk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTXlOb25OZXN0ZWRFeHRlbnNpb24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTXlOb25OZXN0ZWRFeHRlbnNpb24oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNeU5vbk5lc3RlZEV4dGVuc2lvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBNeU5vbk5lc3RlZEV4dGVuc2lvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25fZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NeU5vbk5lc3RlZEV4dGVuc2lvbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk15Tm9uTmVzdGVkRXh0ZW5zaW9uKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTXlOb25OZXN0ZWRFeHRlbnNpb24pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk15Tm9uTmVzdGVkRXh0ZW5zaW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TXlOb25OZXN0ZWRFeHRlbnNpb24+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TXlOb25OZXN0ZWRFeHRlbnNpb24+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBNeU5vbk5lc3RlZEV4dGVuc2lvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15Tm9uTmVzdGVkRXh0ZW5zaW9uPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15Tm9uTmVzdGVkRXh0ZW5zaW9uPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9OTkVTVEVERVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlVG9CZUV4dGVuZGVkIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk1lc3NhZ2VUb0JlRXh0ZW5kZWQsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NeU5vbk5lc3RlZEV4dGVuc2lvbj4gbm9uTmVzdGVkRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb24uTXlOb25OZXN0ZWRFeHRlbnNpb24uY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uLk15Tm9uTmVzdGVkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJRl9GSUVMRF9OVU1CRVIgPSAyMDAwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVRvQmVFeHRlbmRlZCB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbi5NZXNzYWdlVG9CZUV4dGVuZGVkLAogICAgICBqYXZhLmxhbmcuU3RyaW5nPiBpZl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVRvQmVFeHRlbmRlZF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlVG9CZUV4dGVuZGVkX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5vbk5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5vbk5lc3RlZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuLmNvbS9nb29nbGUvcHJvdG9idWYvbm9uX25lc3RlZF9leHRlbnNpIiArCiAgICAgICJvbi5wcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcIlwwMzdcblwwMjNNZXNzYWdlVG8iICsKICAgICAgIkJlRXh0ZW5kZWQqXDAxMFwwMTBcMDAxXDAyMFwyMDBcMjAwXDIwMFwyMDBcMDAyXCJcMDI2XG5cMDI0TXlOb25OZXN0ZWRFeHRlbiIgKwogICAgICAic2lvbjprXG5cMDIybm9uTmVzdGVkRXh0ZW5zaW9uXDAyMiYucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5NZXNzYWdlVG9CZUV4dGVuZGVkXDAzMFwwMDEgXDAwMShcMDEzMlwnLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuTXlOb25OZXN0ZWRFeHRlbnNpb246M1xuXDAwMmlmXDAyMiIgKwogICAgICAiJi5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlVG9CZUV4dGVuZGVkXDAzMCIgKwogICAgICAiXDMyMFwwMTcgXDAwMShcdCIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VUb0JlRXh0ZW5kZWRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZVRvQmVFeHRlbmRlZF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlVG9CZUV4dGVuZGVkX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgbm9uTmVzdGVkRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkpOwogICAgaWZfLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMSkpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAR13L3RyWAAAclgAALQAAAHByb3RvYnVmX3VuaXR0ZXN0L05vbk5lc3RlZEV4dGVuc2lvbkxpdGUuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9ub25fbmVzdGVkX2V4dGVuc2lvbl9saXRlLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBOb25OZXN0ZWRFeHRlbnNpb25MaXRlIHsKICBwcml2YXRlIE5vbk5lc3RlZEV4dGVuc2lvbkxpdGUoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5ub25OZXN0ZWRFeHRlbnNpb25MaXRlKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLnBhY2thZ2VfKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBNZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxNZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZD4gewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQ+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCkKICAgICAgTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWRPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZD4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoNTM2ODcwOTEyLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKQogICAgICBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT05ORVNURURFWFRFTlNJT05MSVRFX0ZJRUxEX05VTUJFUiA9IDE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZCB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlPiBub25OZXN0ZWRFeHRlbnNpb25MaXRlID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk15Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0FHRV9GSUVMRF9OVU1CRVIgPSAyMDA2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUxpdGVUb0JlRXh0ZW5kZWQgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLk1lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkLAogICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gcGFja2FnZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgIG51bGwpOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VMaXRlVG9CZUV4dGVuZGVkX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4zY29tL2dvb2dsZS9wcm90b2J1Zi9ub25fbmVzdGVkX2V4dGVuc2kiICsKICAgICAgIm9uX2xpdGUucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0XCIjXG5cMDI3TWVzcyIgKwogICAgICAiYWdlTGl0ZVRvQmVFeHRlbmRlZCpcMDEwXDAxMFwwMDFcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIlwwMzJcblwwMzBNeU5vbk5lIiArCiAgICAgICJzdGVkRXh0ZW5zaW9uTGl0ZTp3XG5cMDI2bm9uTmVzdGVkRXh0ZW5zaW9uTCIgKwogICAgICAiaXRlXDAyMioucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUxpdGVUb0JlRSIgKwogICAgICAieHRlbmRlZFwwMzBcMDAxIFwwMDEoXDAxMzIrLnByb3RvYnVmX3VuaXR0ZXN0Lk15Tm9uTiIgKwogICAgICAiZXN0ZWRFeHRlbnNpb25MaXRlOjxcblwwMDdwYWNrYWdlXDAyMioucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdC5NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZFwwMzBcMzI2XDAxNyBcMDAxKFwwMTAiICsKICAgICAgIkJcMDAySFwwMDMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlTGl0ZVRvQmVFeHRlbmRlZF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NeU5vbk5lc3RlZEV4dGVuc2lvbkxpdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTXlOb25OZXN0ZWRFeHRlbnNpb25MaXRlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X015Tm9uTmVzdGVkRXh0ZW5zaW9uTGl0ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIG5vbk5lc3RlZEV4dGVuc2lvbkxpdGUuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBwYWNrYWdlXy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEpKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhABFsEokA1wAAANcAADQAAABwcm90b2J1Zl91bml0dGVzdC9PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdDIucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIE91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzIHsKICBwcml2YXRlIE91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXNzYWdlMk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNZXNzYWdlMiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTIpCiAgICAgIFRlc3RNZXNzYWdlMk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1lc3NhZ2UyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlMihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNZXNzYWdlMigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWVzc2FnZTIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBpbnRlcmZhY2UgT3V0ZXJDbGFzc05hbWVUZXN0Mk9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MikKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoaXMgbWVzc2FnZSdzIG5hbWUgaXMgdGhlIHNhbWUgd2l0aCB0aGUgZGVmYXVsdCBvdXRlciBjbGFzcyBuYW1lIG9mIHRoaXMKICAgICAgICogcHJvdG8gZmlsZS4gSXQncyB1c2VkIHRvIHRlc3QgaWYgdGhlIGNvbXBpbGVyIGNhbiBhdm9pZCB0aGlzIGNvbmZsaWN0CiAgICAgICAqIGNvcnJlY3RseS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDJ9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE91dGVyQ2xhc3NOYW1lVGVzdDIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyKQogICAgICAgICAgT3V0ZXJDbGFzc05hbWVUZXN0Mk9yQnVpbGRlciB7CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAgIC8vIFVzZSBPdXRlckNsYXNzTmFtZVRlc3QyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgICAgcHJpdmF0ZSBPdXRlckNsYXNzTmFtZVRlc3QyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgT3V0ZXJDbGFzc05hbWVUZXN0MigpIHsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgICAgcmV0dXJuIG5ldyBPdXRlckNsYXNzTmFtZVRlc3QyKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9PdXRlckNsYXNzTmFtZVRlc3QyX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX05lc3RlZE1lc3NhZ2VfT3V0ZXJDbGFzc05hbWVUZXN0Ml9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0Mi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0Mi5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICAgIHJldHVybiBzaXplOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyKSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgICB9CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIpIG9iajsKCiAgICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgICB9CiAgICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlRnJvbSgKICAgICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MiBwYXJzZUZyb20oCiAgICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MiBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MiBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyIHByb3RvdHlwZSkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhpcyBtZXNzYWdlJ3MgbmFtZSBpcyB0aGUgc2FtZSB3aXRoIHRoZSBkZWZhdWx0IG91dGVyIGNsYXNzIG5hbWUgb2YgdGhpcwogICAgICAgICAqIHByb3RvIGZpbGUuIEl0J3MgdXNlZCB0byB0ZXN0IGlmIHRoZSBjb21waWxlciBjYW4gYXZvaWQgdGhpcyBjb25mbGljdAogICAgICAgICAqIGNvcnJlY3RseS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDJ9CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MikKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0Mk9yQnVpbGRlciB7CiAgICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX05lc3RlZE1lc3NhZ2VfT3V0ZXJDbGFzc05hbWVUZXN0Ml9kZXNjcmlwdG9yOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9PdXRlckNsYXNzTmFtZVRlc3QyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0Mi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0Mi5CdWlsZGVyLmNsYXNzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0Mi5uZXdCdWlsZGVyKCkKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9PdXRlckNsYXNzTmFtZVRlc3QyX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgYnVpbGQoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIodGhpcyk7CiAgICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIpIHsKICAgICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyKW90aGVyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgb3RoZXIpIHsKICAgICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICAgIH0KCgogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MikKICAgICAgICB9CgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyKQogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICBzdGF0aWMgewogICAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QyKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPdXRlckNsYXNzTmFtZVRlc3QyPgogICAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxPdXRlckNsYXNzTmFtZVRlc3QyPigpIHsKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBPdXRlckNsYXNzTmFtZVRlc3QyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3V0ZXJDbGFzc05hbWVUZXN0Mj4gcGFyc2VyKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3V0ZXJDbGFzc05hbWVUZXN0Mj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLk91dGVyQ2xhc3NOYW1lVGVzdDIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIH0KCiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTIuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5OZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMih0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QyT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuVGVzdE1lc3NhZ2UyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2UyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNZXNzYWdlMj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RNZXNzYWdlMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlMj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZTI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDJPdXRlckNsYXNzLlRlc3RNZXNzYWdlMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX05lc3RlZE1lc3NhZ2VfT3V0ZXJDbGFzc05hbWVUZXN0Ml9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9PdXRlckNsYXNzTmFtZVRlc3QyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4wY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3QiICsKICAgICAgImVzdDIucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0XCI2XG5cMDE0VGVzdE1lcyIgKwogICAgICAic2FnZTJcMDMyJlxuXHJOZXN0ZWRNZXNzYWdlXDAzMlwwMjVcblwwMjNPdXRlckNsYXNzTmFtZSIgKwogICAgICAiVGVzdDIiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9OZXN0ZWRNZXNzYWdlX091dGVyQ2xhc3NOYW1lVGVzdDJfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlMl9OZXN0ZWRNZXNzYWdlX091dGVyQ2xhc3NOYW1lVGVzdDJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UyX05lc3RlZE1lc3NhZ2VfT3V0ZXJDbGFzc05hbWVUZXN0Ml9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhABZb84jVlQAA1ZUAADQAAABwcm90b2J1Zl91bml0dGVzdC9PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL291dGVyX2NsYXNzX25hbWVfdGVzdDMucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIE91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzIHsKICBwcml2YXRlIE91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXNzYWdlM09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlM30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNZXNzYWdlMyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTMpCiAgICAgIFRlc3RNZXNzYWdlM09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1lc3NhZ2UzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlMyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNZXNzYWdlMygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWVzc2FnZTMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGlzIGVudW0ncyBuYW1lIGlzIHRoZSBzYW1lIHdpdGggdGhlIGRlZmF1bHQgb3V0ZXIgY2xhc3MgbmFtZSBvZiB0aGlzCiAgICAgICAqIHByb3RvIGZpbGUuIEl0J3MgdXNlZCB0byB0ZXN0IGlmIHRoZSBjb21waWxlciBjYW4gYXZvaWQgdGhpcyBjb25mbGljdAogICAgICAgKiBjb3JyZWN0bHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZS5PdXRlckNsYXNzTmFtZVRlc3QzfQogICAgICAgKi8KICAgICAgcHVibGljIGVudW0gT3V0ZXJDbGFzc05hbWVUZXN0MwogICAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPkRVTU1ZX1ZBTFVFID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgRFVNTVlfVkFMVUUoMSksCiAgICAgICAgOwoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5EVU1NWV9WQUxVRSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZX1ZBTFVFX1ZBTFVFID0gMTsKCgogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICAgIHB1YmxpYyBzdGF0aWMgT3V0ZXJDbGFzc05hbWVUZXN0MyB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBPdXRlckNsYXNzTmFtZVRlc3QzIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgICAgY2FzZSAxOiByZXR1cm4gRFVNTVlfVkFMVUU7CiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE91dGVyQ2xhc3NOYW1lVGVzdDM+CiAgICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgICAgT3V0ZXJDbGFzc05hbWVUZXN0Mz4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8T3V0ZXJDbGFzc05hbWVUZXN0Mz4oKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgT3V0ZXJDbGFzc05hbWVUZXN0MyBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiBPdXRlckNsYXNzTmFtZVRlc3QzLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH07CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT3V0ZXJDbGFzc05hbWVUZXN0M1tdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgICBwdWJsaWMgc3RhdGljIE91dGVyQ2xhc3NOYW1lVGVzdDMgdmFsdWVPZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgICAgcHJpdmF0ZSBPdXRlckNsYXNzTmFtZVRlc3QzKGludCB2YWx1ZSkgewogICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UuT3V0ZXJDbGFzc05hbWVUZXN0MykKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlMy5OZXN0ZWRNZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRNZXNzYWdlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UzKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlM09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdDNPdXRlckNsYXNzLlRlc3RNZXNzYWdlMy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2UzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZTMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5UZXN0TWVzc2FnZTMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZTM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1lc3NhZ2UzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2UzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2UzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlMz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0M091dGVyQ2xhc3MuVGVzdE1lc3NhZ2UzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4wY29tL2dvb2dsZS9wcm90b2J1Zi9vdXRlcl9jbGFzc19uYW1lX3QiICsKICAgICAgImVzdDMucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0XCJHXG5cMDE0VGVzdE1lcyIgKwogICAgICAic2FnZTNcMDMyN1xuXHJOZXN0ZWRNZXNzYWdlXCImXG5cMDIzT3V0ZXJDbGFzc05hbWUiICsKICAgICAgIlRlc3QzXDAyMlwwMTdcblwwMTNEVU1NWV9WQUxVRVwwMjBcMDAxIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlM19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2UzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZTNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAAl7PBy/RgAAv0YAADMAAABwcm90b2J1Zl91bml0dGVzdC9PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvb3V0ZXJfY2xhc3NfbmFtZV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBPdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzIHsKICBwcml2YXRlIE91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgT3V0ZXJDbGFzc05hbWVUZXN0T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGlzIG1lc3NhZ2UncyBuYW1lIGlzIHRoZSBzYW1lIHdpdGggdGhlIGRlZmF1bHQgb3V0ZXIgY2xhc3MgbmFtZSBvZiB0aGlzCiAgICogcHJvdG8gZmlsZS4gSXQncyB1c2VkIHRvIHRlc3QgaWYgdGhlIGNvbXBpbGVyIGNhbiBhdm9pZCB0aGlzIGNvbmZsaWN0CiAgICogY29ycmVjdGx5LgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT3V0ZXJDbGFzc05hbWVUZXN0IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdCkKICAgICAgT3V0ZXJDbGFzc05hbWVUZXN0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBPdXRlckNsYXNzTmFtZVRlc3QubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgT3V0ZXJDbGFzc05hbWVUZXN0KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgT3V0ZXJDbGFzc05hbWVUZXN0KCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE91dGVyQ2xhc3NOYW1lVGVzdCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X091dGVyQ2xhc3NOYW1lVGVzdF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X091dGVyQ2xhc3NOYW1lVGVzdF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3Qgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgbWVzc2FnZSdzIG5hbWUgaXMgdGhlIHNhbWUgd2l0aCB0aGUgZGVmYXVsdCBvdXRlciBjbGFzcyBuYW1lIG9mIHRoaXMKICAgICAqIHByb3RvIGZpbGUuIEl0J3MgdXNlZCB0byB0ZXN0IGlmIHRoZSBjb21waWxlciBjYW4gYXZvaWQgdGhpcyBjb25mbGljdAogICAgICogY29ycmVjdGx5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0KQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X091dGVyQ2xhc3NOYW1lVGVzdF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PdXRlckNsYXNzTmFtZVRlc3RfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PdXRlckNsYXNzTmFtZVRlc3RfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0IHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk91dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuT3V0ZXJDbGFzc05hbWVUZXN0KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3QpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5PdXRlckNsYXNzTmFtZVRlc3RPdXRlckNsYXNzLk91dGVyQ2xhc3NOYW1lVGVzdCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPdXRlckNsYXNzTmFtZVRlc3Q+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8T3V0ZXJDbGFzc05hbWVUZXN0PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgT3V0ZXJDbGFzc05hbWVUZXN0IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3V0ZXJDbGFzc05hbWVUZXN0PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE91dGVyQ2xhc3NOYW1lVGVzdD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuT3V0ZXJDbGFzc05hbWVUZXN0T3V0ZXJDbGFzcy5PdXRlckNsYXNzTmFtZVRlc3QgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3V0ZXJDbGFzc05hbWVUZXN0X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X091dGVyQ2xhc3NOYW1lVGVzdF9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuL2NvbS9nb29nbGUvcHJvdG9idWYvb3V0ZXJfY2xhc3NfbmFtZV90IiArCiAgICAgICJlc3QucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0XCJcMDI0XG5cMDIyT3V0ZXJDbGEiICsKICAgICAgInNzTmFtZVRlc3QiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PdXRlckNsYXNzTmFtZVRlc3RfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3V0ZXJDbGFzc05hbWVUZXN0X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X091dGVyQ2xhc3NOYW1lVGVzdF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhACyvEtM7IQAAOyEAACkAAABwcm90b2J1Zl91bml0dGVzdC9TZXJ2aWNlV2l0aE5vT3V0ZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9tdWx0aXBsZV9maWxlc190ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCi8qKgogKiBQcm90b2J1ZiBzZXJ2aWNlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5TZXJ2aWNlV2l0aE5vT3V0ZXJ9CiAqLwpwdWJsaWMgIGFic3RyYWN0IGNsYXNzIFNlcnZpY2VXaXRoTm9PdXRlcgogICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2UgewogIHByb3RlY3RlZCBTZXJ2aWNlV2l0aE5vT3V0ZXIoKSB7fQoKICBwdWJsaWMgaW50ZXJmYWNlIEludGVyZmFjZSB7CiAgICAvKioKICAgICAqIDxjb2RlPnJwYyBGb28oLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlcikgcmV0dXJucyAoLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmb28oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHJlcXVlc3QsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZG9uZSk7CgogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2UgbmV3UmVmbGVjdGl2ZVNlcnZpY2UoCiAgICAgIGZpbmFsIEludGVyZmFjZSBpbXBsKSB7CiAgICByZXR1cm4gbmV3IFNlcnZpY2VXaXRoTm9PdXRlcigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgIHZvaWQgZm9vKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIgcmVxdWVzdCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGRvbmUpIHsKICAgICAgICBpbXBsLmZvbyhjb250cm9sbGVyLCByZXF1ZXN0LCBkb25lKTsKICAgICAgfQoKICAgIH07CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdTZXJ2aWNlCiAgICAgIG5ld1JlZmxlY3RpdmVCbG9ja2luZ1NlcnZpY2UoZmluYWwgQmxvY2tpbmdJbnRlcmZhY2UgaW1wbCkgewogICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nU2VydmljZSgpIHsKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgY2FsbEJsb2NraW5nTWV0aG9kKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIHJlcXVlc3QpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHsKICAgICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiU2VydmljZS5jYWxsQmxvY2tpbmdNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3IgIiArCiAgICAgICAgICAgICJ3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICByZXR1cm4gaW1wbC5mb28oY29udHJvbGxlciwgKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlcilyZXF1ZXN0KTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgICAgZ2V0UmVxdWVzdFByb3RvdHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiU2VydmljZS5nZXRSZXF1ZXN0UHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKSB7CiAgICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIlNlcnZpY2UuZ2V0UmVzcG9uc2VQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgIiArCiAgICAgICAgICAgICJkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgICB9CiAgICAgIH0KCiAgICB9OwogIH0KCiAgLyoqCiAgICogPGNvZGU+cnBjIEZvbygucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyKSByZXR1cm5zICgucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKTs8L2NvZGU+CiAgICovCiAgcHVibGljIGFic3RyYWN0IHZvaWQgZm9vKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHJlcXVlc3QsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGRvbmUpOwoKICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NdWx0aXBsZUZpbGVzVGVzdFByb3RvLmdldERlc2NyaXB0b3IoKS5nZXRTZXJ2aWNlcygpLmdldCgwKTsKICB9CiAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgcHVibGljIGZpbmFsIHZvaWQgY2FsbE1ldGhvZCgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSByZXF1ZXN0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZT4gZG9uZSkgewogICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICJTZXJ2aWNlLmNhbGxNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3Igd3JvbmcgIiArCiAgICAgICAgInNlcnZpY2UgdHlwZS4iKTsKICAgIH0KICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICBjYXNlIDA6CiAgICAgICAgdGhpcy5mb28oY29udHJvbGxlciwgKHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlcilyZXF1ZXN0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNVdGlsLjxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz5zcGVjaWFsaXplQ2FsbGJhY2soCiAgICAgICAgICAgIGRvbmUpKTsKICAgICAgICByZXR1cm47CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICB9CiAgfQoKICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgIGdldFJlcXVlc3RQcm90b3R5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAiU2VydmljZS5nZXRSZXF1ZXN0UHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICJkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICB9CiAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgY2FzZSAwOgogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlV2l0aE5vT3V0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICB9CiAgfQoKICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgIGdldFJlc3BvbnNlUHJvdG90eXBlKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKSB7CiAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgIlNlcnZpY2UuZ2V0UmVzcG9uc2VQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgIiArCiAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgIH0KICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICBjYXNlIDA6CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgfQogIH0KCiAgcHVibGljIHN0YXRpYyBTdHViIG5ld1N0dWIoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICByZXR1cm4gbmV3IFN0dWIoY2hhbm5lbCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0dWIgZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5TZXJ2aWNlV2l0aE5vT3V0ZXIgaW1wbGVtZW50cyBJbnRlcmZhY2UgewogICAgcHJpdmF0ZSBTdHViKGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgY2hhbm5lbDsKCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGdldENoYW5uZWwoKSB7CiAgICAgIHJldHVybiBjaGFubmVsOwogICAgfQoKICAgIHB1YmxpYyAgdm9pZCBmb28oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHJlcXVlc3QsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZG9uZSkgewogICAgICBjaGFubmVsLmNhbGxNZXRob2QoCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoMCksCiAgICAgICAgY29udHJvbGxlciwKICAgICAgICByZXF1ZXN0LAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjVXRpbC5nZW5lcmFsaXplQ2FsbGJhY2soCiAgICAgICAgICBkb25lLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOwogICAgfQogIH0KCiAgcHVibGljIHN0YXRpYyBCbG9ja2luZ0ludGVyZmFjZSBuZXdCbG9ja2luZ1N0dWIoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdScGNDaGFubmVsIGNoYW5uZWwpIHsKICAgIHJldHVybiBuZXcgQmxvY2tpbmdTdHViKGNoYW5uZWwpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBCbG9ja2luZ0ludGVyZmFjZSB7CiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZm9vKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VXaXRoTm9PdXRlciByZXF1ZXN0KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VFeGNlcHRpb247CiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBCbG9ja2luZ1N0dWIgaW1wbGVtZW50cyBCbG9ja2luZ0ludGVyZmFjZSB7CiAgICBwcml2YXRlIEJsb2NraW5nU3R1Yihjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nUnBjQ2hhbm5lbCBjaGFubmVsOwoKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBmb28oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZVdpdGhOb091dGVyIHJlcXVlc3QpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZUV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIGNoYW5uZWwuY2FsbEJsb2NraW5nTWV0aG9kKAogICAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDApLAogICAgICAgIGNvbnRyb2xsZXIsCiAgICAgICAgcmVxdWVzdCwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CgogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlNlcnZpY2VXaXRoTm9PdXRlcikKfQoKUEsDBAoAAAAAAAAAIQDBOmIbI14AACNeAAAxAAAAcHJvdG9idWZfdW5pdHRlc3QvVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9jYWNoZWRfZmllbGRfc2l6ZV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCi8qKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZX0KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBUZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlKQogICAgVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2VPckJ1aWxkZXIgewpwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAvLyBVc2UgVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIFRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UoKSB7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgIHJldHVybiBuZXcgVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuQ2FjaGVkRmllbGRTaXplVGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkNhY2hlZEZpZWxkU2l6ZVRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgfQoKICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPMl9DSElMRF9GSUVMRF9OVU1CRVIgPSAxOwogIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgcHJvdG8yQ2hpbGRfOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8yX2NoaWxkID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzJDaGlsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvMkNoaWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvMl9jaGlsZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHByb3RvMkNoaWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgZ2V0UHJvdG8yQ2hpbGQoKSB7CiAgICByZXR1cm4gcHJvdG8yQ2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHByb3RvMkNoaWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwcm90bzJfY2hpbGQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIGdldFByb3RvMkNoaWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIHByb3RvMkNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwcm90bzJDaGlsZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UTzNfQ0hJTERfRklFTERfTlVNQkVSID0gMjsKICBwcml2YXRlIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcHJvdG8zQ2hpbGRfOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zQ2hpbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNDaGlsZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgcHJvdG8zQ2hpbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIGdldFByb3RvM0NoaWxkKCkgewogICAgcmV0dXJuIHByb3RvM0NoaWxkXyA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHByb3RvM0NoaWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIGdldFByb3RvM0NoaWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIHByb3RvM0NoaWxkXyA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHByb3RvM0NoaWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHByb3RvdHlwZSkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgfQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgcmV0dXJuIGJ1aWxkZXI7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlKQogICAgICBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZU9yQnVpbGRlciB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5DYWNoZWRGaWVsZFNpemVUZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LkNhY2hlZEZpZWxkU2l6ZVRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgfQoKICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBzdXBlcihwYXJlbnQpOwogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CiAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICBnZXRQcm90bzJDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldFByb3RvM0NoaWxkRmllbGRCdWlsZGVyKCk7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICBzdXBlci5jbGVhcigpOwogICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgcHJvdG8yQ2hpbGRfID0gbnVsbDsKICAgICAgaWYgKHByb3RvMkNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHByb3RvMkNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIHByb3RvMkNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIHByb3RvM0NoaWxkXyA9IG51bGw7CiAgICAgIGlmIChwcm90bzNDaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBwcm90bzNDaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBwcm90bzNDaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5DYWNoZWRGaWVsZFNpemVUZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIGJ1aWxkKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSh0aGlzKTsKICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgb25CdWlsdCgpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5wcm90bzJDaGlsZF8gPSBwcm90bzJDaGlsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBwcm90bzJDaGlsZF8KICAgICAgICAgICAgOiBwcm90bzJDaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgcmVzdWx0LnByb3RvM0NoaWxkXyA9IHByb3RvM0NoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICA/IHByb3RvM0NoaWxkXwogICAgICAgICAgICA6IHByb3RvM0NoaWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgcHJvdG8yQ2hpbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlcj4gcHJvdG8yQ2hpbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwcm90bzJfY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8yQ2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzJDaGlsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvMl9jaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8yQ2hpbGQuCiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBnZXRQcm90bzJDaGlsZCgpIHsKICAgICAgaWYgKHByb3RvMkNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBwcm90bzJDaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcHJvdG8yQ2hpbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBwcm90bzJDaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvMl9jaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRQcm90bzJDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyB2YWx1ZSkgewogICAgICBpZiAocHJvdG8yQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBwcm90bzJDaGlsZF8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwcm90bzJDaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvMl9jaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRQcm90bzJDaGlsZCgKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAocHJvdG8yQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcHJvdG8yQ2hpbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJvdG8yQ2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwcm90bzJfY2hpbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQcm90bzJDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyB2YWx1ZSkgewogICAgICBpZiAocHJvdG8yQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICBwcm90bzJDaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgcHJvdG8yQ2hpbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRQcm90bzJDaGlsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwcm90bzJDaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJvdG8yQ2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmIChwcm90bzJDaGlsZF8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwcm90bzJfY2hpbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzJDaGlsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICBwcm90bzJDaGlsZF8gPSBudWxsOwogICAgICBpZiAocHJvdG8yQ2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcHJvdG8yQ2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgcHJvdG8yQ2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvMl9jaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciBnZXRQcm90bzJDaGlsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRQcm90bzJDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwcm90bzJfY2hpbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIGdldFByb3RvMkNoaWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAocHJvdG8yQ2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMkNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBwcm90bzJDaGlsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcHJvdG8yQ2hpbGRfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8yX2NoaWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFByb3RvMkNoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAocHJvdG8yQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcHJvdG8yQ2hpbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0UHJvdG8yQ2hpbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHByb3RvMkNoaWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvMkNoaWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIHByb3RvM0NoaWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXI+IHByb3RvM0NoaWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNDaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM0NoaWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zQ2hpbGQuCiAgICAgKi8KICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIGdldFByb3RvM0NoaWxkKCkgewogICAgICBpZiAocHJvdG8zQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM0NoaWxkXyA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHByb3RvM0NoaWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gcHJvdG8zQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM0NoaWxkKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgdmFsdWUpIHsKICAgICAgaWYgKHByb3RvM0NoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcHJvdG8zQ2hpbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJvdG8zQ2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM0NoaWxkKAogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHByb3RvM0NoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHByb3RvM0NoaWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHByb3RvM0NoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVByb3RvM0NoaWxkKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgdmFsdWUpIHsKICAgICAgaWYgKHByb3RvM0NoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgcHJvdG8zQ2hpbGRfICE9IG51bGwgJiYKICAgICAgICAgIHByb3RvM0NoaWxkXyAhPSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRQcm90bzNDaGlsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwcm90bzNDaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJvdG8zQ2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmIChwcm90bzNDaGlsZF8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJvdG8zQ2hpbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgcHJvdG8zQ2hpbGRfID0gbnVsbDsKICAgICAgaWYgKHByb3RvM0NoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHByb3RvM0NoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIHByb3RvM0NoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIgZ2V0UHJvdG8zQ2hpbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0UHJvdG8zQ2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciBnZXRQcm90bzNDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKHByb3RvM0NoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBwcm90bzNDaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gcHJvdG8zQ2hpbGRfID09IG51bGwgPwogICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcHJvdG8zQ2hpbGRfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRQcm90bzNDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKHByb3RvM0NoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHByb3RvM0NoaWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldFByb3RvM0NoaWxkKCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBwcm90bzNDaGlsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBwcm90bzNDaGlsZEJ1aWxkZXJfOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlKQogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlKQogIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZT4KICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2U+KCkgewogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIFRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgdHJ5IHsKICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9CiAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgfQogIH07CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2U+IHBhcnNlcigpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhY2hlZEZpZWxkU2l6ZU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCn0KClBLAwQKAAAAAAAAACEASqtyDrQFAAC0BQAAOgAAAHByb3RvYnVmX3VuaXR0ZXN0L1Rlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlT3JCdWlsZGVyLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvY2FjaGVkX2ZpZWxkX3NpemVfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgaW50ZXJmYWNlIFRlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZSkKICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8yX2NoaWxkID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzJDaGlsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNQcm90bzJDaGlsZCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8yX2NoaWxkID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgcHJvdG8yQ2hpbGQuCiAgICovCiAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgZ2V0UHJvdG8yQ2hpbGQoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvMl9jaGlsZCA9IDE7PC9jb2RlPgogICAqLwogIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIGdldFByb3RvMkNoaWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHByb3RvM19jaGlsZCA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zQ2hpbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzUHJvdG8zQ2hpbGQoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwcm90bzNfY2hpbGQgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBwcm90bzNDaGlsZC4KICAgKi8KICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIGdldFByb3RvM0NoaWxkKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcHJvdG8zX2NoaWxkID0gMjs8L2NvZGU+CiAgICovCiAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciBnZXRQcm90bzNDaGlsZE9yQnVpbGRlcigpOwp9ClBLAwQKAAAAAAAAACEAB024KYxrAACMawAAKAAAAHByb3RvYnVmX3VuaXR0ZXN0L1Rlc3RDdXN0b21PcHRpb25zLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgVGVzdEN1c3RvbU9wdGlvbnMgewogIHByaXZhdGUgVGVzdEN1c3RvbU9wdGlvbnMoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZ2V0RmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNPckJ1aWxkZXIgZ2V0RmllbGRPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcikKICAgICAgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBnZXRGaWVsZCgpIHsKICAgICAgcmV0dXJuIGZpZWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc09yQnVpbGRlciBnZXRGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZpZWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldEZpZWxkKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0RmllbGQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKSBvYmo7CgogICAgICBpZiAoaGFzRmllbGQoKSAhPSBvdGhlci5oYXNGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0RmllbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZpZWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkXyA9IGZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZmllbGRfCiAgICAgICAgICAgICAgOiBmaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5UZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkKCkpIHsKICAgICAgICAgIG1lcmdlRmllbGQob3RoZXIuZ2V0RmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zT3JCdWlsZGVyPiBmaWVsZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGdldEZpZWxkKCkgewogICAgICAgIGlmIChmaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWVsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgdmFsdWUpIHsKICAgICAgICBpZiAoZmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgZmllbGRfICE9IG51bGwgJiYKICAgICAgICAgICAgZmllbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZmllbGRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuQnVpbGRlciBnZXRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc09yQnVpbGRlciBnZXRGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWVsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGaWVsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpZWxkQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4tY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0X2N1c3RvbV9vcHRpb24iICsKICAgICAgInMucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0XDAzMi1nb29nbGUvcHJvdG8iICsKICAgICAgImJ1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90b1wiZ1xuJVRlcyIgKwogICAgICAidE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lclwwMjI+XG5cMDA1ZmkiICsKICAgICAgImVsZFwwMzBcMDAxIFwwMDEoXDAxMzIvLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWciICsKICAgICAgImVXaXRoQ3VzdG9tT3B0aW9ucyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zQ29udGFpbmVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc0NvbnRhaW5lcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGQiLCB9KTsKICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQA/C48Z4j8AAOI/AAAhAAAAcHJvdG9idWZfdW5pdHRlc3QvVGltaW5nQmVsdC5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBjb20vZ29vZ2xlL3Byb3RvYnVmL25lc3RlZF9idWlsZGVyc190ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCi8qKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0fQogKi8KcHVibGljIGZpbmFsIGNsYXNzIFRpbWluZ0JlbHQgZXh0ZW5kcwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0KQogICAgVGltaW5nQmVsdE9yQnVpbGRlciB7CnByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogIC8vIFVzZSBUaW1pbmdCZWx0Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgcHJpdmF0ZSBUaW1pbmdCZWx0KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgVGltaW5nQmVsdCgpIHsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgcmV0dXJuIG5ldyBUaW1pbmdCZWx0KCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UaW1pbmdCZWx0X2Rlc2NyaXB0b3I7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGltaW5nQmVsdF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5CdWlsZGVyLmNsYXNzKTsKICB9CgogIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTlVNQkVSX09GX1RFRVRIX0ZJRUxEX05VTUJFUiA9IDE7CiAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZUZWV0aF8gPSAwOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bWJlcl9vZl90ZWV0aCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtYmVyT2ZUZWV0aCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc051bWJlck9mVGVldGgoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bWJlcl9vZl90ZWV0aCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG51bWJlck9mVGVldGguCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0TnVtYmVyT2ZUZWV0aCgpIHsKICAgIHJldHVybiBudW1iZXJPZlRlZXRoXzsKICB9CgogIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG51bWJlck9mVGVldGhfKTsKICAgIH0KICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgIHNpemUgPSAwOwogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG51bWJlck9mVGVldGhfKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQpKSB7CiAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgIH0KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCkgb2JqOwoKICAgIGlmIChoYXNOdW1iZXJPZlRlZXRoKCkgIT0gb3RoZXIuaGFzTnVtYmVyT2ZUZWV0aCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzTnVtYmVyT2ZUZWV0aCgpKSB7CiAgICAgIGlmIChnZXROdW1iZXJPZlRlZXRoKCkKICAgICAgICAgICE9IG90aGVyLmdldE51bWJlck9mVGVldGgoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgfQogICAgaW50IGhhc2ggPSA0MTsKICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgaWYgKGhhc051bWJlck9mVGVldGgoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOVU1CRVJfT0ZfVEVFVEhfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXROdW1iZXJPZlRlZXRoKCk7CiAgICB9CiAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgcmV0dXJuIGhhc2g7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBwYXJzZUZyb20oCiAgICAgIGJ5dGVbXSBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogIH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHByb3RvdHlwZSkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgfQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgcmV0dXJuIGJ1aWxkZXI7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCkKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdE9yQnVpbGRlciB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGltaW5nQmVsdF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UaW1pbmdCZWx0X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICB9CgogICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICBudW1iZXJPZlRlZXRoXyA9IDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UaW1pbmdCZWx0X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgYnVpbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBidWlsZFBhcnRpYWwoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQodGhpcyk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0IHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5udW1iZXJPZlRlZXRoXyA9IG51bWJlck9mVGVldGhfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCkgewogICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQpb3RoZXIpOwogICAgICB9IGVsc2UgewogICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCBvdGhlcikgewogICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgIGlmIChvdGhlci5oYXNOdW1iZXJPZlRlZXRoKCkpIHsKICAgICAgICBzZXROdW1iZXJPZlRlZXRoKG90aGVyLmdldE51bWJlck9mVGVldGgoKSk7CiAgICAgIH0KICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgbnVtYmVyT2ZUZWV0aF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gLy8gZmluYWxseQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZUZWV0aF8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1iZXJfb2ZfdGVldGggPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbnVtYmVyT2ZUZWV0aCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc051bWJlck9mVGVldGgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtYmVyX29mX3RlZXRoID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXJPZlRlZXRoLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE51bWJlck9mVGVldGgoKSB7CiAgICAgIHJldHVybiBudW1iZXJPZlRlZXRoXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbnVtYmVyX29mX3RlZXRoID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlck9mVGVldGggdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXROdW1iZXJPZlRlZXRoKGludCB2YWx1ZSkgewoKICAgICAgbnVtYmVyT2ZUZWV0aF8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bWJlcl9vZl90ZWV0aCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck51bWJlck9mVGVldGgoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgbnVtYmVyT2ZUZWV0aF8gPSAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGltaW5nQmVsdCkKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0KQogIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5UaW1pbmdCZWx0KCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUaW1pbmdCZWx0PgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUaW1pbmdCZWx0PigpIHsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBUaW1pbmdCZWx0IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgdHJ5IHsKICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9CiAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgfQogIH07CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGltaW5nQmVsdD4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGltaW5nQmVsdD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCn0KClBLAwQKAAAAAAAAACEAYruLunQCAAB0AgAAKgAAAHByb3RvYnVmX3VuaXR0ZXN0L1RpbWluZ0JlbHRPckJ1aWxkZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgaW50ZXJmYWNlIFRpbWluZ0JlbHRPckJ1aWxkZXIgZXh0ZW5kcwogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRpbWluZ0JlbHQpCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBudW1iZXJfb2ZfdGVldGggPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bWJlck9mVGVldGggZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzTnVtYmVyT2ZUZWV0aCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG51bWJlcl9vZl90ZWV0aCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG51bWJlck9mVGVldGguCiAgICovCiAgaW50IGdldE51bWJlck9mVGVldGgoKTsKfQpQSwMECgAAAAAAAAAhAAzUYsEheAAAIXgAAB4AAABwcm90b2J1Zl91bml0dGVzdC9WZWhpY2xlLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2J1aWxkZXJzX3Rlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKLyoqCiAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGV9CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgVmVoaWNsZSBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUpCiAgICBWZWhpY2xlT3JCdWlsZGVyIHsKcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgLy8gVXNlIFZlaGljbGUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIFZlaGljbGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICBzdXBlcihidWlsZGVyKTsKICB9CiAgcHJpdmF0ZSBWZWhpY2xlKCkgewogICAgd2hlZWxfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IFZlaGljbGUoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkQnVpbGRlcnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1ZlaGljbGVfZGVzY3JpcHRvcjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WZWhpY2xlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlLkJ1aWxkZXIuY2xhc3MpOwogIH0KCiAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkdJTkVfRklFTERfTlVNQkVSID0gMTsKICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBlbmdpbmVfOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZW5naW5lID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbmdpbmUgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNFbmdpbmUoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZW5naW5lID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZW5naW5lLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGdldEVuZ2luZSgpIHsKICAgIHJldHVybiBlbmdpbmVfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbmdpbmVfOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGVuZ2luZSA9IDE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lT3JCdWlsZGVyIGdldEVuZ2luZU9yQnVpbGRlcigpIHsKICAgIHJldHVybiBlbmdpbmVfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbmdpbmVfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0hFRUxfRklFTERfTlVNQkVSID0gMjsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsPiB3aGVlbF87CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5XaGVlbD4gZ2V0V2hlZWxMaXN0KCkgewogICAgcmV0dXJuIHdoZWVsXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWxPckJ1aWxkZXI+IAogICAgICBnZXRXaGVlbE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gd2hlZWxfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRXaGVlbENvdW50KCkgewogICAgcmV0dXJuIHdoZWVsXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgZ2V0V2hlZWwoaW50IGluZGV4KSB7CiAgICByZXR1cm4gd2hlZWxfLmdldChpbmRleCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWxPckJ1aWxkZXIgZ2V0V2hlZWxPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIHdoZWVsXy5nZXQoaW5kZXgpOwogIH0KCiAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRFbmdpbmUoKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHdoZWVsXy5zaXplKCk7IGkrKykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIHdoZWVsXy5nZXQoaSkpOwogICAgfQogICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgc2l6ZSA9IDA7CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRFbmdpbmUoKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHdoZWVsXy5zaXplKCk7IGkrKykgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIHdoZWVsXy5nZXQoaSkpOwogICAgfQogICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICByZXR1cm4gc2l6ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgIGlmIChvYmogPT0gdGhpcykgewogICAgIHJldHVybiB0cnVlOwogICAgfQogICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSkpIHsKICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgfQogICAgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlKSBvYmo7CgogICAgaWYgKGhhc0VuZ2luZSgpICE9IG90aGVyLmhhc0VuZ2luZSgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzRW5naW5lKCkpIHsKICAgICAgaWYgKCFnZXRFbmdpbmUoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRFbmdpbmUoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmICghZ2V0V2hlZWxMaXN0KCkKICAgICAgICAuZXF1YWxzKG90aGVyLmdldFdoZWVsTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgfQogICAgaW50IGhhc2ggPSA0MTsKICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgaWYgKGhhc0VuZ2luZSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVOR0lORV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEVuZ2luZSgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0V2hlZWxDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBXSEVFTF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFdoZWVsTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgcmV0dXJuIGhhc2g7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSBwYXJzZUZyb20oCiAgICAgIGJ5dGVbXSBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogIH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIHByb3RvdHlwZSkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgfQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgcmV0dXJuIGJ1aWxkZXI7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSkKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZU9yQnVpbGRlciB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmVoaWNsZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WZWhpY2xlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZS5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgfQoKICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBzdXBlcihwYXJlbnQpOwogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CiAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICBnZXRFbmdpbmVGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXRXaGVlbEZpZWxkQnVpbGRlcigpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgIGVuZ2luZV8gPSBudWxsOwogICAgICBpZiAoZW5naW5lQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGVuZ2luZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBlbmdpbmVCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHdoZWVsXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbF8gPSBudWxsOwogICAgICAgIHdoZWVsQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WZWhpY2xlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgYnVpbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUodGhpcyk7CiAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSByZXN1bHQpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgd2hlZWxfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3Qod2hlZWxfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LndoZWVsXyA9IHdoZWVsXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQud2hlZWxfID0gd2hlZWxCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSByZXN1bHQpIHsKICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICByZXN1bHQuZW5naW5lXyA9IGVuZ2luZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBlbmdpbmVfCiAgICAgICAgICAgIDogZW5naW5lQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUpIHsKICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlKW90aGVyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICB9CgogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUgb3RoZXIpIHsKICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICBpZiAob3RoZXIuaGFzRW5naW5lKCkpIHsKICAgICAgICBtZXJnZUVuZ2luZShvdGhlci5nZXRFbmdpbmUoKSk7CiAgICAgIH0KICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIud2hlZWxfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHdoZWVsXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgd2hlZWxfID0gb3RoZXIud2hlZWxfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVXaGVlbElzTXV0YWJsZSgpOwogICAgICAgICAgICB3aGVlbF8uYWRkQWxsKG90aGVyLndoZWVsXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci53aGVlbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAod2hlZWxCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgd2hlZWxCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHdoZWVsQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICB3aGVlbF8gPSBvdGhlci53aGVlbF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgICAgd2hlZWxCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldFdoZWVsRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2hlZWxCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci53aGVlbF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHRyeSB7CiAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEVuZ2luZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBtID0KICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbC5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlV2hlZWxJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoZWVsXy5hZGQobSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHdoZWVsQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IC8vIGZpbmFsbHkKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGVuZ2luZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lLCBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lT3JCdWlsZGVyPiBlbmdpbmVCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBlbmdpbmUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZW5naW5lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzRW5naW5lKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZW5naW5lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbmdpbmUuCiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZ2V0RW5naW5lKCkgewogICAgICBpZiAoZW5naW5lQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBlbmdpbmVfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbmdpbmVfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBlbmdpbmVCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBlbmdpbmUgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RW5naW5lKHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSB2YWx1ZSkgewogICAgICBpZiAoZW5naW5lQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5naW5lXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGVuZ2luZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGVuZ2luZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRFbmdpbmUoCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChlbmdpbmVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5naW5lXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGVuZ2luZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGVuZ2luZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUVuZ2luZShwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgdmFsdWUpIHsKICAgICAgaWYgKGVuZ2luZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgIGVuZ2luZV8gIT0gbnVsbCAmJgogICAgICAgICAgZW5naW5lXyAhPSBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldEVuZ2luZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBlbmdpbmVfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGVuZ2luZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGVuZ2luZV8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBlbmdpbmUgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbmdpbmUoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgZW5naW5lXyA9IG51bGw7CiAgICAgIGlmIChlbmdpbmVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZW5naW5lQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIGVuZ2luZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZW5naW5lID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuQnVpbGRlciBnZXRFbmdpbmVCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0RW5naW5lRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGVuZ2luZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuRW5naW5lT3JCdWlsZGVyIGdldEVuZ2luZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKGVuZ2luZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gZW5naW5lQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBlbmdpbmVfID09IG51bGwgPwogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbmdpbmVfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZW5naW5lID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUsIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmVPckJ1aWxkZXI+IAogICAgICAgIGdldEVuZ2luZUZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGVuZ2luZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbmdpbmVCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUsIHByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0RW5naW5lKCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBlbmdpbmVfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gZW5naW5lQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5XaGVlbD4gd2hlZWxfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVdoZWVsSXNNdXRhYmxlKCkgewogICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgd2hlZWxfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuV2hlZWw+KHdoZWVsXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLCBwcm90b2J1Zl91bml0dGVzdC5XaGVlbC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5XaGVlbE9yQnVpbGRlcj4gd2hlZWxCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuV2hlZWw+IGdldFdoZWVsTGlzdCgpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh3aGVlbF8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB3aGVlbEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0V2hlZWxDb3VudCgpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB3aGVlbF8uc2l6ZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB3aGVlbEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBnZXRXaGVlbChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB3aGVlbF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gd2hlZWxCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0V2hlZWwoCiAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCB2YWx1ZSkgewogICAgICBpZiAod2hlZWxCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVXaGVlbElzTXV0YWJsZSgpOwogICAgICAgIHdoZWVsXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFdoZWVsKAogICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVdoZWVsSXNNdXRhYmxlKCk7CiAgICAgICAgd2hlZWxfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHdoZWVsQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkV2hlZWwocHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgdmFsdWUpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlV2hlZWxJc011dGFibGUoKTsKICAgICAgICB3aGVlbF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkV2hlZWwoCiAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCB2YWx1ZSkgewogICAgICBpZiAod2hlZWxCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVXaGVlbElzTXV0YWJsZSgpOwogICAgICAgIHdoZWVsXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFdoZWVsKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh3aGVlbEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVXaGVlbElzTXV0YWJsZSgpOwogICAgICAgIHdoZWVsXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHdoZWVsQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRXaGVlbCgKICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh3aGVlbEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVXaGVlbElzTXV0YWJsZSgpOwogICAgICAgIHdoZWVsXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFdoZWVsKAogICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWw+IHZhbHVlcykgewogICAgICBpZiAod2hlZWxCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlV2hlZWxJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgd2hlZWxfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcldoZWVsKCkgewogICAgICBpZiAod2hlZWxCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgd2hlZWxfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3aGVlbEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVXaGVlbChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVdoZWVsSXNNdXRhYmxlKCk7CiAgICAgICAgd2hlZWxfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgd2hlZWxCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLkJ1aWxkZXIgZ2V0V2hlZWxCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0V2hlZWxGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbE9yQnVpbGRlciBnZXRXaGVlbE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB3aGVlbF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHdoZWVsQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWxPckJ1aWxkZXI+IAogICAgICAgICBnZXRXaGVlbE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmICh3aGVlbEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gd2hlZWxCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh3aGVlbF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuQnVpbGRlciBhZGRXaGVlbEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRXaGVlbEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuQnVpbGRlciBhZGRXaGVlbEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRXaGVlbEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLkJ1aWxkZXI+IAogICAgICAgICBnZXRXaGVlbEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0V2hlZWxGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwsIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsT3JCdWlsZGVyPiAKICAgICAgICBnZXRXaGVlbEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKHdoZWVsQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHdoZWVsQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCwgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWxPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgd2hlZWxfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICB3aGVlbF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB3aGVlbEJ1aWxkZXJfOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlZlaGljbGUpCiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSkKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVmVoaWNsZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCiAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VmVoaWNsZT4KICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VmVoaWNsZT4oKSB7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgVmVoaWNsZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgIHRyeSB7CiAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfQogICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgIH0KICB9OwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFZlaGljbGU+IHBhcnNlcigpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFZlaGljbGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9Cgp9CgpQSwMECgAAAAAAAAAhAIRD3uuoBQAAqAUAACcAAABwcm90b2J1Zl91bml0dGVzdC9WZWhpY2xlT3JCdWlsZGVyLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2J1aWxkZXJzX3Rlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGludGVyZmFjZSBWZWhpY2xlT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5WZWhpY2xlKQogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBlbmdpbmUgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVuZ2luZSBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNFbmdpbmUoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW5naW5lIGVuZ2luZSA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGVuZ2luZS4KICAgKi8KICBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmUgZ2V0RW5naW5lKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVuZ2luZSBlbmdpbmUgPSAxOzwvY29kZT4KICAgKi8KICBwcm90b2J1Zl91bml0dGVzdC5FbmdpbmVPckJ1aWxkZXIgZ2V0RW5naW5lT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsPiAKICAgICAgZ2V0V2hlZWxMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHdoZWVsID0gMjs8L2NvZGU+CiAgICovCiAgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgZ2V0V2hlZWwoaW50IGluZGV4KTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgd2hlZWwgPSAyOzwvY29kZT4KICAgKi8KICBpbnQgZ2V0V2hlZWxDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbE9yQnVpbGRlcj4gCiAgICAgIGdldFdoZWVsT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5XaGVlbCB3aGVlbCA9IDI7PC9jb2RlPgogICAqLwogIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsT3JCdWlsZGVyIGdldFdoZWVsT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpOwp9ClBLAwQKAAAAAAAAACEAf7mcyjxGAAA8RgAAHAAAAHByb3RvYnVmX3VuaXR0ZXN0L1doZWVsLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGNvbS9nb29nbGUvcHJvdG9idWYvbmVzdGVkX2J1aWxkZXJzX3Rlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKLyoqCiAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsfQogKi8KcHVibGljIGZpbmFsIGNsYXNzIFdoZWVsIGV4dGVuZHMKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuV2hlZWwpCiAgICBXaGVlbE9yQnVpbGRlciB7CnByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogIC8vIFVzZSBXaGVlbC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogIHByaXZhdGUgV2hlZWwoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICBzdXBlcihidWlsZGVyKTsKICB9CiAgcHJpdmF0ZSBXaGVlbCgpIHsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgcmV0dXJuIG5ldyBXaGVlbCgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZGVzY3JpcHRvcjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZEJ1aWxkZXJzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9XaGVlbF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLkJ1aWxkZXIuY2xhc3MpOwogIH0KCiAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSQURJVVNfRklFTERfTlVNQkVSID0gMTsKICBwcml2YXRlIGludCByYWRpdXNfID0gMDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiByYWRpdXMgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJhZGl1cyBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1JhZGl1cygpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcmFkaXVzID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgcmFkaXVzLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFJhZGl1cygpIHsKICAgIHJldHVybiByYWRpdXNfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0lEVEhfRklFTERfTlVNQkVSID0gMjsKICBwcml2YXRlIGludCB3aWR0aF8gPSAwOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHdpZHRoID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSB3aWR0aCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1dpZHRoKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB3aWR0aCA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHdpZHRoLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFdpZHRoKCkgewogICAgcmV0dXJuIHdpZHRoXzsKICB9CgogIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHJhZGl1c18pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIHdpZHRoXyk7CiAgICB9CiAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICBzaXplID0gMDsKICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCByYWRpdXNfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCB3aWR0aF8pOwogICAgfQogICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICByZXR1cm4gc2l6ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgIGlmIChvYmogPT0gdGhpcykgewogICAgIHJldHVybiB0cnVlOwogICAgfQogICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwpKSB7CiAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgIH0KICAgIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsKSBvYmo7CgogICAgaWYgKGhhc1JhZGl1cygpICE9IG90aGVyLmhhc1JhZGl1cygpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzUmFkaXVzKCkpIHsKICAgICAgaWYgKGdldFJhZGl1cygpCiAgICAgICAgICAhPSBvdGhlci5nZXRSYWRpdXMoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc1dpZHRoKCkgIT0gb3RoZXIuaGFzV2lkdGgoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc1dpZHRoKCkpIHsKICAgICAgaWYgKGdldFdpZHRoKCkKICAgICAgICAgICE9IG90aGVyLmdldFdpZHRoKCkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgIH0KICAgIGludCBoYXNoID0gNDE7CiAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgIGlmIChoYXNSYWRpdXMoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSQURJVVNfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSYWRpdXMoKTsKICAgIH0KICAgIGlmIChoYXNXaWR0aCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFdJRFRIX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0V2lkdGgoKTsKICAgIH0KICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICByZXR1cm4gaGFzaDsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHBhcnNlRnJvbSgKICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsIHByb3RvdHlwZSkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgfQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgcmV0dXJuIGJ1aWxkZXI7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LldoZWVsKQogICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbE9yQnVpbGRlciB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLm5ld0J1aWxkZXIoKQogICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgIH0KCiAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgc3VwZXIocGFyZW50KTsKCiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgIHJhZGl1c18gPSAwOwogICAgICB3aWR0aF8gPSAwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRCdWlsZGVycy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfV2hlZWxfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBidWlsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgYnVpbGRQYXJ0aWFsKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwodGhpcyk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5XaGVlbCByZXN1bHQpIHsKICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICByZXN1bHQucmFkaXVzXyA9IHJhZGl1c187CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgcmVzdWx0LndpZHRoXyA9IHdpZHRoXzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuV2hlZWwpb3RoZXIpOwogICAgICB9IGVsc2UgewogICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgb3RoZXIpIHsKICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LldoZWVsLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgaWYgKG90aGVyLmhhc1JhZGl1cygpKSB7CiAgICAgICAgc2V0UmFkaXVzKG90aGVyLmdldFJhZGl1cygpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzV2lkdGgoKSkgewogICAgICAgIHNldFdpZHRoKG90aGVyLmdldFdpZHRoKCkpOwogICAgICB9CiAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgdHJ5IHsKICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgIHJhZGl1c18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICB3aWR0aF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IC8vIGZpbmFsbHkKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgIHByaXZhdGUgaW50IHJhZGl1c18gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiByYWRpdXMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmFkaXVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUmFkaXVzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJhZGl1cyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmFkaXVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJhZGl1cygpIHsKICAgICAgcmV0dXJuIHJhZGl1c187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJhZGl1cyA9IDE7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSByYWRpdXMgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRSYWRpdXMoaW50IHZhbHVlKSB7CgogICAgICByYWRpdXNfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiByYWRpdXMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSYWRpdXMoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgcmFkaXVzXyA9IDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGludCB3aWR0aF8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB3aWR0aCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB3aWR0aCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1dpZHRoKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHdpZHRoID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB3aWR0aC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRXaWR0aCgpIHsKICAgICAgcmV0dXJuIHdpZHRoXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgd2lkdGggPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgd2lkdGggdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRXaWR0aChpbnQgdmFsdWUpIHsKCiAgICAgIHdpZHRoXyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgd2lkdGggPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJXaWR0aCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICB3aWR0aF8gPSAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuV2hlZWwpCiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuV2hlZWwpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuV2hlZWwgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFdoZWVsPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxXaGVlbD4oKSB7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgV2hlZWwgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxXaGVlbD4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8V2hlZWw+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5XaGVlbCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKfQoKUEsDBAoAAAAAAAAAIQBw7h9TGgMAABoDAAAlAAAAcHJvdG9idWZfdW5pdHRlc3QvV2hlZWxPckJ1aWxkZXIuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9uZXN0ZWRfYnVpbGRlcnNfdGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgaW50ZXJmYWNlIFdoZWVsT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5XaGVlbCkKICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJhZGl1cyA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmFkaXVzIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1JhZGl1cygpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJhZGl1cyA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHJhZGl1cy4KICAgKi8KICBpbnQgZ2V0UmFkaXVzKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHdpZHRoID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSB3aWR0aCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNXaWR0aCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHdpZHRoID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgd2lkdGguCiAgICovCiAgaW50IGdldFdpZHRoKCk7Cn0KUEsDBAoAAAAAAAAAIQAUkVY54HYDAOB2AwA9AAAAcHJvdG9idWZfdW5pdHRlc3QvbGl0ZV9lcXVhbHNfYW5kX2hhc2gvTGl0ZUVxdWFsc0FuZEhhc2guamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogY29tL2dvb2dsZS9wcm90b2J1Zi9saXRlX2VxdWFsc19hbmRfaGFzaC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2g7CgpwdWJsaWMgZmluYWwgY2xhc3MgTGl0ZUVxdWFsc0FuZEhhc2ggewogIHByaXZhdGUgTGl0ZUVxdWFsc0FuZEhhc2goKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2gudmFyaW50KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5maXhlZDMyKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5maXhlZDY0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5teUdyb3VwKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuZm9vRXh0KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBUZXN0T25lb2ZFcXVhbHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdE9uZW9mRXF1YWxzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTmFtZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmFtZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbmFtZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TmFtZUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiB2YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICovCiAgICBpbnQgZ2V0VmFsdWUoKTsKCiAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMuT25lb2ZGaWVsZENhc2UgZ2V0T25lb2ZGaWVsZENhc2UoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdE9uZW9mRXF1YWxzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE9uZW9mRXF1YWxzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RPbmVvZkVxdWFscykKICAgICAgVGVzdE9uZW9mRXF1YWxzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0T25lb2ZFcXVhbHMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE9uZW9mRXF1YWxzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE9uZW9mRXF1YWxzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RPbmVvZkVxdWFscygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9UZXN0T25lb2ZFcXVhbHNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdE9uZW9mRXF1YWxzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgcHVibGljIGVudW0gT25lb2ZGaWVsZENhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgTkFNRSgxKSwKICAgICAgVkFMVUUoMiksCiAgICAgIE9ORU9GRklFTERfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgT25lb2ZGaWVsZENhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBOQU1FOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gVkFMVUU7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBPTkVPRkZJRUxEX05PVF9TRVQ7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIE9uZW9mRmllbGRDYXNlCiAgICBnZXRPbmVvZkZpZWxkQ2FzZSgpIHsKICAgICAgcmV0dXJuIE9uZW9mRmllbGRDYXNlLmZvck51bWJlcigKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuYW1lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzTmFtZSgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmFtZS4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxKSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TmFtZUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX05VTUJFUiA9IDI7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFZhbHVlKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDIpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMikgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKAogICAgICAgICAgICAyLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMiwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscykgb2JqOwoKICAgICAgaWYgKCFnZXRPbmVvZkZpZWxkQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIGlmICghZ2V0TmFtZSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXROYW1lKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBpZiAoZ2V0VmFsdWUoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldFZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgc3dpdGNoIChvbmVvZkZpZWxkQ2FzZV8pIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOQU1FX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5hbWUoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0T25lb2ZFcXVhbHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0T25lb2ZFcXVhbHMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9UZXN0T25lb2ZFcXVhbHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RPbmVvZkVxdWFsc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9UZXN0T25lb2ZFcXVhbHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyByZXN1bHQpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZENhc2VfID0gb25lb2ZGaWVsZENhc2VfOwogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IHRoaXMub25lb2ZGaWVsZF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0T25lb2ZFcXVhbHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBzd2l0Y2ggKG90aGVyLmdldE9uZW9mRmllbGRDYXNlKCkpIHsKICAgICAgICAgIGNhc2UgTkFNRTogewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG90aGVyLm9uZW9mRmllbGRfOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIFZBTFVFOiB7CiAgICAgICAgICAgIHNldFZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZGSUVMRF9OT1RfU0VUOiB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb25lb2ZGaWVsZF87CiAgICAgIHB1YmxpYyBPbmVvZkZpZWxkQ2FzZQogICAgICAgICAgZ2V0T25lb2ZGaWVsZENhc2UoKSB7CiAgICAgICAgcmV0dXJuIE9uZW9mRmllbGRDYXNlLmZvck51bWJlcigKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZkZpZWxkKCkgewogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc05hbWUoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuYW1lLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxKSB7CiAgICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXROYW1lQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmFtZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOYW1lKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbmFtZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5hbWVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDIpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKGludCB2YWx1ZSkgewoKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAyOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIHZhbHVlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAyKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RPbmVvZkVxdWFscykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdE9uZW9mRXF1YWxzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdE9uZW9mRXF1YWxzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uZW9mRXF1YWxzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RPbmVvZkVxdWFscz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RPbmVvZkVxdWFscyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZkVxdWFscz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T25lb2ZFcXVhbHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RPbmVvZkVxdWFscyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEZvb09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb28pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8Rm9vPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICovCiAgICBpbnQgZ2V0VmFsdWUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcj4gCiAgICAgICAgZ2V0QmFyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgZ2V0QmFyKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRCYXJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyT3JCdWlsZGVyPiAKICAgICAgICBnZXRCYXJPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhck9yQnVpbGRlciBnZXRCYXJPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNeU1hcENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNeU1hcCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE15TWFwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0TXlNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0TXlNYXBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAzOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TXlNYXBPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBzaW50NjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc2ludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IHNpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2ludDY0LgogICAgICovCiAgICBsb25nIGdldFNpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgTXlHcm91cCA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTXlHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBNeUdyb3VwID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlncm91cC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgZ2V0TXlHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBNeUdyb3VwID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cE9yQnVpbGRlciBnZXRNeUdyb3VwT3JCdWlsZGVyKCk7CgogICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLlNpbmdsZUNhc2UgZ2V0U2luZ2xlQ2FzZSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb299CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb28gZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBGb28+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb28pCiAgICAgIEZvb09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgRm9vLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEZvbyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28sID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvbygpIHsKICAgICAgYmFyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBGb28oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBNeUdyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vLk15R3JvdXApCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzVmFsdWUoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICAgKi8KICAgICAgaW50IGdldFZhbHVlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBMSU5UOiBBTExPV19HUk9VUFMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkZvby5NeUdyb3VwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE15R3JvdXAgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkZvby5NeUdyb3VwKQogICAgICAgIE15R3JvdXBPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBNeUdyb3VwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTXlHcm91cChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE15R3JvdXAoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTXlHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeUdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fTXlHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgdmFsdWVfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXApKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwKSBvYmo7CgogICAgICAgIGlmIChoYXNWYWx1ZSgpICE9IG90aGVyLmhhc1ZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgICAgaWYgKGdldFZhbHVlKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VmFsdWUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTElOVDogQUxMT1dfR1JPVVBTCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb28uTXlHcm91cH0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vLk15R3JvdXApCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX015R3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fTXlHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgdmFsdWVfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeUdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICAgIHNldFZhbHVlKG90aGVyLmdldFZhbHVlKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIHZhbHVlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHZhbHVlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgICByZXR1cm4gdmFsdWVfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgICB2YWx1ZV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb28uTXlHcm91cCkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkZvby5NeUdyb3VwKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15R3JvdXA+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNeUdyb3VwPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE15R3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNeUdyb3VwPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TXlHcm91cD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBzaW5nbGVDYXNlXyA9IDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzaW5nbGVfOwogICAgcHVibGljIGVudW0gU2luZ2xlQ2FzZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2UuSW50ZXJuYWxPbmVPZkVudW0gewogICAgICBTSU5UNjQoNCksCiAgICAgIE1ZR1JPVVAoNSksCiAgICAgIFNJTkdMRV9OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBTaW5nbGVDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgU2luZ2xlQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIFNpbmdsZUNhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgNDogcmV0dXJuIFNJTlQ2NDsKICAgICAgICAgIGNhc2UgNTogcmV0dXJuIE1ZR1JPVVA7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBTSU5HTEVfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgU2luZ2xlQ2FzZQogICAgZ2V0U2luZ2xlQ2FzZSgpIHsKICAgICAgcmV0dXJuIFNpbmdsZUNhc2UuZm9yTnVtYmVyKAogICAgICAgICAgc2luZ2xlQ2FzZV8pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRWYWx1ZSgpIHsKICAgICAgcmV0dXJuIHZhbHVlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXI+IGJhcl87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXI+IGdldEJhckxpc3QoKSB7CiAgICAgIHJldHVybiBiYXJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhck9yQnVpbGRlcj4gCiAgICAgICAgZ2V0QmFyT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGJhcl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QmFyQ291bnQoKSB7CiAgICAgIHJldHVybiBiYXJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBnZXRCYXIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBiYXJfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJPckJ1aWxkZXIgZ2V0QmFyT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gYmFyXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1ZX01BUF9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fTXlNYXBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbXlNYXBfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldE15TWFwKCkgewogICAgICBpZiAobXlNYXBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBteU1hcF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE15TWFwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc015TWFwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE15TWFwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TXlNYXAoKSB7CiAgICAgIHJldHVybiBnZXRNeU1hcE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNeU1hcE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TXlNYXBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IHNpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzaW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTaW50NjQoKSB7CiAgICAgIHJldHVybiBzaW5nbGVDYXNlXyA9PSA0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgc2ludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldFNpbnQ2NCgpIHsKICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDQpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5Mb25nKSBzaW5nbGVfOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNWUdST1VQX0ZJRUxEX05VTUJFUiA9IDU7CiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIE15R3JvdXAgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15Z3JvdXAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeUdyb3VwKCkgewogICAgICByZXR1cm4gc2luZ2xlQ2FzZV8gPT0gNTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgTXlHcm91cCA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG15Z3JvdXAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBnZXRNeUdyb3VwKCkgewogICAgICBpZiAoc2luZ2xlQ2FzZV8gPT0gNSkgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwKSBzaW5nbGVfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgTXlHcm91cCA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwT3JCdWlsZGVyIGdldE15R3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChzaW5nbGVDYXNlXyA9PSA1KSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXApIHNpbmdsZV87CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbz4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgdmFsdWVfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhcl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGJhcl8uZ2V0KGkpKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TXlNYXAoKSwKICAgICAgICAgIE15TWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBpZiAoc2luZ2xlQ2FzZV8gPT0gNCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgKICAgICAgICAgICAgNCwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgc2luZ2xlXykpOwogICAgICB9CiAgICAgIGlmIChzaW5nbGVDYXNlXyA9PSA1KSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoNSwgKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwKSBzaW5nbGVfKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzA5MTIsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHZhbHVlXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYXJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGJhcl8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIG15TWFwX18gPSBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgbXlNYXBfXyk7CiAgICAgIH0KICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSgKICAgICAgICAgICAgICA0LCAobG9uZykoKGphdmEubGFuZy5Mb25nKSBzaW5nbGVfKSk7CiAgICAgIH0KICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDUpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDUsIChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCkgc2luZ2xlXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vKSBvYmo7CgogICAgICBpZiAoaGFzVmFsdWUoKSAhPSBvdGhlci5oYXNWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgaWYgKGdldFZhbHVlKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0VmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0QmFyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJhckxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE15TWFwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNeU1hcCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFNpbmdsZUNhc2UoKS5lcXVhbHMob3RoZXIuZ2V0U2luZ2xlQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKHNpbmdsZUNhc2VfKSB7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgaWYgKGdldFNpbnQ2NCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0U2ludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIGlmICghZ2V0TXlHcm91cCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNeUdyb3VwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFZhbHVlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEJhckNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYXJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNWV9NQVBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TXlNYXAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIHN3aXRjaCAoc2luZ2xlQ2FzZV8pIHsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgICBnZXRTaW50NjQoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNWUdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE15R3JvdXAoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb28pCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYXJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIGJhckJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmNsZWFyKCk7CiAgICAgICAgaWYgKG15R3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBteUdyb3VwQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgc2luZ2xlQ2FzZV8gPSAwOwogICAgICAgIHNpbmdsZV8gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyByZXN1bHQpIHsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIGJhcl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChiYXJfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJhcl8gPSBiYXJfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQuYmFyXyA9IGJhckJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28gcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudmFsdWVfID0gdmFsdWVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm15TWFwXyA9IGludGVybmFsR2V0TXlNYXAoKTsKICAgICAgICAgIHJlc3VsdC5teU1hcF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyByZXN1bHQpIHsKICAgICAgICByZXN1bHQuc2luZ2xlQ2FzZV8gPSBzaW5nbGVDYXNlXzsKICAgICAgICByZXN1bHQuc2luZ2xlXyA9IHRoaXMuc2luZ2xlXzsKICAgICAgICBpZiAoc2luZ2xlQ2FzZV8gPT0gNSAmJgogICAgICAgICAgICBteUdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LnNpbmdsZV8gPSBteUdyb3VwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbywgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28sIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28sIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICBzZXRWYWx1ZShvdGhlci5nZXRWYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIuYmFyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGJhcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgYmFyXyA9IG90aGVyLmJhcl87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZUJhcklzTXV0YWJsZSgpOwogICAgICAgICAgICAgIGJhcl8uYWRkQWxsKG90aGVyLmJhcl8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLmJhcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChiYXJCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBiYXJCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgYmFyQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIGJhcl8gPSBvdGhlci5iYXJfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgICAgICBiYXJCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRCYXJGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgYmFyQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuYmFyXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TXlNYXAoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHN3aXRjaCAob3RoZXIuZ2V0U2luZ2xlQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIFNJTlQ2NDogewogICAgICAgICAgICBzZXRTaW50NjQob3RoZXIuZ2V0U2ludDY0KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgTVlHUk9VUDogewogICAgICAgICAgICBtZXJnZU15R3JvdXAob3RoZXIuZ2V0TXlHcm91cCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIFNJTkdMRV9OT1RfU0VUOiB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgdmFsdWVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlQmFySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIGJhcl8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgYmFyQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIG15TWFwX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbXlNYXBfXy5nZXRLZXkoKSwgbXlNYXBfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIHNpbmdsZV8gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBzaW5nbGVDYXNlXyA9IDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDQzOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoNSwKICAgICAgICAgICAgICAgICAgICBnZXRNeUdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIHNpbmdsZUNhc2VfID0gNTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IHNpbmdsZUNhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHNpbmdsZV87CiAgICAgIHB1YmxpYyBTaW5nbGVDYXNlCiAgICAgICAgICBnZXRTaW5nbGVDYXNlKCkgewogICAgICAgIHJldHVybiBTaW5nbGVDYXNlLmZvck51bWJlcigKICAgICAgICAgICAgc2luZ2xlQ2FzZV8pOwogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNpbmdsZSgpIHsKICAgICAgICBzaW5nbGVDYXNlXyA9IDA7CiAgICAgICAgc2luZ2xlXyA9IG51bGw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCB2YWx1ZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlKGludCB2YWx1ZSkgewoKICAgICAgICB2YWx1ZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHZhbHVlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyPiBiYXJfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVCYXJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgYmFyXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcj4oYmFyXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJPckJ1aWxkZXI+IGJhckJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyPiBnZXRCYXJMaXN0KCkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoYmFyXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBiYXJCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0QmFyQ291bnQoKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGJhckJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBnZXRCYXIoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBiYXJCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXIoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciB2YWx1ZSkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUJhcklzTXV0YWJsZSgpOwogICAgICAgICAgYmFyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlQmFySXNNdXRhYmxlKCk7CiAgICAgICAgICBiYXJfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhckJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRCYXIocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHZhbHVlKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlQmFySXNNdXRhYmxlKCk7CiAgICAgICAgICBiYXJfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFyQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQmFyKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgdmFsdWUpIHsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVCYXJJc011dGFibGUoKTsKICAgICAgICAgIGJhcl8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFyQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEJhcigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVCYXJJc011dGFibGUoKTsKICAgICAgICAgIGJhcl8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRCYXIoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVCYXJJc011dGFibGUoKTsKICAgICAgICAgIGJhcl8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFyQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEJhcigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyPiB2YWx1ZXMpIHsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlQmFySXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCBiYXJfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFyKCkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYXJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhckJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQmFyKGludCBpbmRleCkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVCYXJJc011dGFibGUoKTsKICAgICAgICAgIGJhcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuQnVpbGRlciBnZXRCYXJCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldEJhckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhck9yQnVpbGRlciBnZXRCYXJPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGJhcl8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYmFyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJPckJ1aWxkZXI+IAogICAgICAgICAgIGdldEJhck9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoYmFyXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyIGJhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5CdWlsZGVyIGFkZEJhckJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEJhckZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIgYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLkJ1aWxkZXIgYWRkQmFyQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRCYXJGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhciBiYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0QmFyQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldEJhckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0QmFyRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYXJCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgYmFyXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJhckJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBteU1hcF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNeU1hcCgpIHsKICAgICAgICBpZiAobXlNYXBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTXlNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG15TWFwXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkgewogICAgICAgIGlmIChteU1hcF8gPT0gbnVsbCkgewogICAgICAgICAgbXlNYXBfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNeU1hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW15TWFwXy5pc011dGFibGUoKSkgewogICAgICAgICAgbXlNYXBfID0gbXlNYXBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBteU1hcF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNeU1hcENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc015TWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE15TWFwTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNeU1hcCgpIHsKICAgICAgICByZXR1cm4gZ2V0TXlNYXBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TXlNYXBNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXlNYXAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TXlNYXBPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE15TWFwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNeU1hcE9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNeU1hcCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNeU1hcCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbXlfbWFwID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNeU1hcCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTXlNYXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTXlNYXAoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNeU1hcCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBteV9tYXAgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE15TWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG15X21hcCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTXlNYXAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU15TWFwKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgc2ludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc2ludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gc2luZ2xlQ2FzZV8gPT0gNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IHNpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRTaW50NjQoKSB7CiAgICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDQpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIHNpbmdsZV87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwTDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IHNpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIHNpbmdsZUNhc2VfID0gNDsKICAgICAgICBzaW5nbGVfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBzaW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTaW50NjQoKSB7CiAgICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDQpIHsKICAgICAgICAgIHNpbmdsZUNhc2VfID0gMDsKICAgICAgICAgIHNpbmdsZV8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXBPckJ1aWxkZXI+IG15R3JvdXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIE15R3JvdXAgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc015R3JvdXAoKSB7CiAgICAgICAgcmV0dXJuIHNpbmdsZUNhc2VfID09IDU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIE15R3JvdXAgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG15Z3JvdXAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCBnZXRNeUdyb3VwKCkgewogICAgICAgIGlmIChteUdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDUpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCkgc2luZ2xlXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDUpIHsKICAgICAgICAgICAgcmV0dXJuIG15R3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBNeUdyb3VwID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TXlHcm91cChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChteUdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBzaW5nbGVfID0gdmFsdWU7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbXlHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBzaW5nbGVDYXNlXyA9IDU7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIE15R3JvdXAgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNeUdyb3VwKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobXlHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHNpbmdsZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBteUdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHNpbmdsZUNhc2VfID0gNTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgTXlHcm91cCA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTXlHcm91cChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChteUdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDUgJiYKICAgICAgICAgICAgICBzaW5nbGVfICE9IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIHNpbmdsZV8gPSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cC5uZXdCdWlsZGVyKChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cCkgc2luZ2xlXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2luZ2xlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChzaW5nbGVDYXNlXyA9PSA1KSB7CiAgICAgICAgICAgIG15R3JvdXBCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbXlHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzaW5nbGVDYXNlXyA9IDU7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIE15R3JvdXAgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck15R3JvdXAoKSB7CiAgICAgICAgaWYgKG15R3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoc2luZ2xlQ2FzZV8gPT0gNSkgewogICAgICAgICAgICBzaW5nbGVDYXNlXyA9IDA7CiAgICAgICAgICAgIHNpbmdsZV8gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHNpbmdsZUNhc2VfID09IDUpIHsKICAgICAgICAgICAgc2luZ2xlQ2FzZV8gPSAwOwogICAgICAgICAgICBzaW5nbGVfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG15R3JvdXBCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgTXlHcm91cCA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cC5CdWlsZGVyIGdldE15R3JvdXBCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRNeUdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBNeUdyb3VwID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXBPckJ1aWxkZXIgZ2V0TXlHcm91cE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKHNpbmdsZUNhc2VfID09IDUpICYmIChteUdyb3VwQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBteUdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoc2luZ2xlQ2FzZV8gPT0gNSkgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwKSBzaW5nbGVfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgTXlHcm91cCA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28uTXlHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNeUdyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChteUdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCEoc2luZ2xlQ2FzZV8gPT0gNSkpIHsKICAgICAgICAgICAgc2luZ2xlXyA9IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgfQogICAgICAgICAgbXlHcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLk15R3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvby5NeUdyb3VwKSBzaW5nbGVfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgc2luZ2xlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHNpbmdsZUNhc2VfID0gNTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbXlHcm91cEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkZvbykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9vPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvbz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEZvbyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvbz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb28+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEJhck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuYW1lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOYW1lKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuYW1lLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXROYW1lQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQmFyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhcikKICAgICAgQmFyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBCYXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQmFyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQmFyKCkgewogICAgICBuYW1lXyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEJhcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5BTUVfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG5hbWVfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNOYW1lKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuYW1lLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG5hbWVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIG5hbWVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TmFtZUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG5hbWVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBuYW1lXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBuYW1lXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgbmFtZV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcikgb2JqOwoKICAgICAgaWYgKGhhc05hbWUoKSAhPSBvdGhlci5oYXNOYW1lKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc05hbWUoKSkgewogICAgICAgIGlmICghZ2V0TmFtZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TmFtZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc05hbWUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5BTUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5hbWUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Jhcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbmFtZV8gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Jhcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubmFtZV8gPSBuYW1lXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNOYW1lKCkpIHsKICAgICAgICAgIG5hbWVfID0gb3RoZXIubmFtZV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgbmFtZV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbmFtZV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOYW1lKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbmFtZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBuYW1lXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG5hbWVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TmFtZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbmFtZV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG5hbWVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmFtZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG5hbWVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5hbWUoKSB7CiAgICAgICAgbmFtZV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXROYW1lKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBuYW1lIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmFtZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBuYW1lXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxCYXI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCYXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QmFyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0VYVF9GSUVMRF9OVU1CRVIgPSAxMDA7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28sCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyPiBmb29FeHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXIuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLmNsYXNzLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQmFyUHJpbWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyUHJpbWUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuYW1lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOYW1lKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuYW1lLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXROYW1lQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyUHJpbWV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCYXJQcmltZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXJQcmltZSkKICAgICAgQmFyUHJpbWVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEJhclByaW1lLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEJhclByaW1lKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQmFyUHJpbWUoKSB7CiAgICAgIG5hbWVfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQmFyUHJpbWUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyUHJpbWVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyUHJpbWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5BTUVfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG5hbWVfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNOYW1lKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuYW1lLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG5hbWVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIG5hbWVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBuYW1lLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TmFtZUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG5hbWVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBuYW1lXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBuYW1lXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgbmFtZV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSkgb2JqOwoKICAgICAgaWYgKGhhc05hbWUoKSAhPSBvdGhlci5oYXNOYW1lKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc05hbWUoKSkgewogICAgICAgIGlmICghZ2V0TmFtZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TmFtZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc05hbWUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5BTUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5hbWUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhclByaW1lfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guQmFyUHJpbWUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0JhclByaW1lX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJQcmltZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbmFtZV8gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0JhclByaW1lX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubmFtZV8gPSBuYW1lXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc05hbWUoKSkgewogICAgICAgICAgbmFtZV8gPSBvdGhlci5uYW1lXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBuYW1lXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBuYW1lXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuYW1lIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc05hbWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuYW1lLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG5hbWVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbmFtZV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG5hbWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXROYW1lQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBuYW1lXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbmFtZV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5hbWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROYW1lKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbmFtZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTmFtZSgpIHsKICAgICAgICBuYW1lXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE5hbWUoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG5hbWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROYW1lQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG5hbWVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkJhclByaW1lKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXJQcmltZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkJhclByaW1lKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5CYXJQcmltZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhclByaW1lPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEJhclByaW1lPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQmFyUHJpbWUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXJQcmltZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXJQcmltZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guQmFyUHJpbWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBFbXB0eU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5FbXB0eSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRW1wdHl9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5FbXB0eSkKICAgICAgRW1wdHlPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEVtcHR5Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEVtcHR5KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRW1wdHkoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRW1wdHkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRW1wdHlfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRW1wdHlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5KSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkVtcHR5fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRW1wdHkpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHlPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0VtcHR5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9FbXB0eV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9FbXB0eV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5KHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5KW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5FbXB0eSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRW1wdHkpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5FbXB0eSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRW1wdHkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxFbXB0eT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxFbXB0eT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEVtcHR5IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RW1wdHk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RW1wdHk+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkVtcHR5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTXlHcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5NeUdyb3VwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGdyb3VwX3ZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGdyb3VwVmFsdWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0dyb3VwVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGdyb3VwX3ZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBncm91cFZhbHVlLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEdyb3VwVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGdyb3VwX3ZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZ3JvdXBWYWx1ZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0R3JvdXBWYWx1ZUJ5dGVzKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLk15R3JvdXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNeUdyb3VwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLk15R3JvdXApCiAgICAgIE15R3JvdXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE15R3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTXlHcm91cChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE15R3JvdXAoKSB7CiAgICAgIGdyb3VwVmFsdWVfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTXlHcm91cCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9NeUdyb3VwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX015R3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHUk9VUF9WQUxVRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgZ3JvdXBWYWx1ZV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGdyb3VwX3ZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGdyb3VwVmFsdWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNHcm91cFZhbHVlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBncm91cF92YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZ3JvdXBWYWx1ZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0R3JvdXBWYWx1ZSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBncm91cFZhbHVlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBncm91cFZhbHVlXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBncm91cF92YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGdyb3VwVmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRHcm91cFZhbHVlQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZ3JvdXBWYWx1ZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGdyb3VwVmFsdWVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIGdyb3VwVmFsdWVfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBncm91cFZhbHVlXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwKSBvYmo7CgogICAgICBpZiAoaGFzR3JvdXBWYWx1ZSgpICE9IG90aGVyLmhhc0dyb3VwVmFsdWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzR3JvdXBWYWx1ZSgpKSB7CiAgICAgICAgaWYgKCFnZXRHcm91cFZhbHVlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRHcm91cFZhbHVlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzR3JvdXBWYWx1ZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgR1JPVVBfVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEdyb3VwVmFsdWUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTXlHcm91cH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLk15R3JvdXApCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfTXlHcm91cF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfTXlHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZ3JvdXBWYWx1ZV8gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX015R3JvdXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZ3JvdXBWYWx1ZV8gPSBncm91cFZhbHVlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXApIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5NeUdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzR3JvdXBWYWx1ZSgpKSB7CiAgICAgICAgICBncm91cFZhbHVlXyA9IG90aGVyLmdyb3VwVmFsdWVfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGdyb3VwVmFsdWVfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGdyb3VwVmFsdWVfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZ3JvdXBfdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBncm91cFZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0dyb3VwVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZ3JvdXBfdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZ3JvdXBWYWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEdyb3VwVmFsdWUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBncm91cFZhbHVlXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGdyb3VwVmFsdWVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBncm91cF92YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZ3JvdXBWYWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEdyb3VwVmFsdWVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGdyb3VwVmFsdWVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBncm91cFZhbHVlXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBncm91cF92YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGdyb3VwVmFsdWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRHcm91cFZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZ3JvdXBWYWx1ZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBncm91cF92YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckdyb3VwVmFsdWUoKSB7CiAgICAgICAgZ3JvdXBWYWx1ZV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRHcm91cFZhbHVlKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZ3JvdXBfdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZ3JvdXBWYWx1ZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEdyb3VwVmFsdWVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZ3JvdXBWYWx1ZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTXlHcm91cCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTXlHcm91cCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15R3JvdXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TXlHcm91cD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE15R3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNeUdyb3VwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE15R3JvdXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UmVjdXJzaXZlT25lb2ZPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1IoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgZ2V0UigpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHIgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mT3JCdWlsZGVyIGdldFJPckJ1aWxkZXIoKTsKCiAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YuRm9vQ2FzZSBnZXRGb29DYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZWN1cnNpdmVPbmVvZiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0UmVjdXJzaXZlT25lb2YpCiAgICAgIFRlc3RSZWN1cnNpdmVPbmVvZk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFJlY3Vyc2l2ZU9uZW9mLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZWN1cnNpdmVPbmVvZihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZWN1cnNpdmVPbmVvZigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UmVjdXJzaXZlT25lb2YoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdFJlY3Vyc2l2ZU9uZW9mX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RSZWN1cnNpdmVPbmVvZl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGZvb0Nhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGZvb187CiAgICBwdWJsaWMgZW51bSBGb29DYXNlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICAgIFIoMSksCiAgICAgIEZPT19OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBGb29DYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgRm9vQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIEZvb0Nhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIFI7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBGT09fTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgRm9vQ2FzZQogICAgZ2V0Rm9vQ2FzZSgpIHsKICAgICAgcmV0dXJuIEZvb0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgZm9vQ2FzZV8pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJfRklFTERfTlVNQkVSID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIGdldFIoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgciA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mT3JCdWlsZGVyIGdldFJPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZikgZm9vXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YpIGZvb18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZikgb2JqOwoKICAgICAgaWYgKCFnZXRGb29DYXNlKCkuZXF1YWxzKG90aGVyLmdldEZvb0Nhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgc3dpdGNoIChmb29DYXNlXykgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIGlmICghZ2V0UigpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIHN3aXRjaCAoZm9vQ2FzZV8pIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFIoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2ZPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RSZWN1cnNpdmVPbmVvZl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdFJlY3Vyc2l2ZU9uZW9mX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAockJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9UZXN0UmVjdXJzaXZlT25lb2ZfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByZXN1bHQpIHsKICAgICAgICByZXN1bHQuZm9vQ2FzZV8gPSBmb29DYXNlXzsKICAgICAgICByZXN1bHQuZm9vXyA9IHRoaXMuZm9vXzsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSAmJgogICAgICAgICAgICByQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LmZvb18gPSByQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2Ygb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBzd2l0Y2ggKG90aGVyLmdldEZvb0Nhc2UoKSkgewogICAgICAgICAgY2FzZSBSOiB7CiAgICAgICAgICAgIG1lcmdlUihvdGhlci5nZXRSKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgICAgcHVibGljIEZvb0Nhc2UKICAgICAgICAgIGdldEZvb0Nhc2UoKSB7CiAgICAgICAgcmV0dXJuIEZvb0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICBmb29DYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vKCkgewogICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZk9yQnVpbGRlcj4gckJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgciBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1IoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSByLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIGdldFIoKSB7CiAgICAgICAgaWYgKHJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZikgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgICAgIHJldHVybiByQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgciA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Uihwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgdmFsdWUpIHsKICAgICAgICBpZiAockJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFIoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAockJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZvb18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVIocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIHZhbHVlKSB7CiAgICAgICAgaWYgKHJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSAmJgogICAgICAgICAgICAgIGZvb18gIT0gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mKSBmb29fKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICAgICAgckJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclIoKSB7CiAgICAgICAgaWYgKHJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLkJ1aWxkZXIgZ2V0UkJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5UZXN0UmVjdXJzaXZlT25lb2YgciA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mT3JCdWlsZGVyIGdldFJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChmb29DYXNlXyA9PSAxKSAmJiAockJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gckJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YpIGZvb187CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiByID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2ZPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAockJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKGZvb0Nhc2VfID09IDEpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2YsIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5UZXN0UmVjdXJzaXZlT25lb2ZPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAocHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mKSBmb29fLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gckJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLlRlc3RSZWN1cnNpdmVPbmVvZikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guVGVzdFJlY3Vyc2l2ZU9uZW9mIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlY3Vyc2l2ZU9uZW9mPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZWN1cnNpdmVPbmVvZj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZWN1cnNpdmVPbmVvZiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZWN1cnNpdmVPbmVvZj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlT25lb2Y+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLlRlc3RSZWN1cnNpdmVPbmVvZiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQVJJTlRfRklFTERfTlVNQkVSID0gMTAxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gdmFyaW50ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDEwMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkZvbyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLkZvbywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGZpeGVkMzIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJWEVENjRfRklFTERfTlVNQkVSID0gMTAzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guRm9vIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guRm9vLAogICAgICBqYXZhLmxhbmcuTG9uZz4gZml4ZWQ2NCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVlHUk9VUF9GSUVMRF9OVU1CRVIgPSAxMDQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb28geyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5MaXRlRXF1YWxzQW5kSGFzaC5Gb28sCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXA+IG15R3JvdXAgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkxpdGVFcXVhbHNBbmRIYXNoLk15R3JvdXAuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guTGl0ZUVxdWFsc0FuZEhhc2guTXlHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdE9uZW9mRXF1YWxzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RPbmVvZkVxdWFsc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX015TWFwRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX015TWFwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeUdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeUdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJQcmltZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJQcmltZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRW1wdHlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRW1wdHlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX015R3JvdXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfTXlHcm91cF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdFJlY3Vyc2l2ZU9uZW9mX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RSZWN1cnNpdmVPbmVvZl9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuLmNvbS9nb29nbGUvcHJvdG9idWYvbGl0ZV9lcXVhbHNfYW5kX2hhIiArCiAgICAgICJzaC5wcm90b1wwMjImcHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfIiArCiAgICAgICJhbmRfaGFzaFwiQVxuXDAxN1Rlc3RPbmVvZkVxdWFsc1wwMjJcMDE2XG5cMDA0bmFtZVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcdEhcMDAwXDAyMlwwMTdcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNUhcMDAwQlxyXG5cMDEzb25lb2ZfZmllbGRcIlwzMTRcMDAyXG5cMDAzIiArCiAgICAgICJGb29cMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI4XG5cMDAzYmFyXDAzMFwwMDIgXDAwMyhcMDEzMisucHJvdG9iIiArCiAgICAgICJ1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5CYXJcMDIyRlxuXDAwNiIgKwogICAgICAibXlfbWFwXDAzMFwwMDMgXDAwMyhcMDEzMjYucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcSIgKwogICAgICAidWFsc19hbmRfaGFzaC5Gb28uTXlNYXBFbnRyeVwwMjJcMDIwXG5cMDA2c2ludDY0XDAzMFwwMDQiICsKICAgICAgIiBcMDAxKFwwMjJIXDAwMFwwMjJGXG5cMDA3bXlncm91cFwwMzBcMDA1IFwwMDEoXG4yMy5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkZvby5NeUdyb3VwSFwwMDBcMDMyLCIgKwogICAgICAiXG5cbk15TWFwRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQiICsKICAgICAgIjpcMDAyOFwwMDFcMDMyXDAzMFxuXDAwN015R3JvdXBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwNSpcMDEwXDAxMGRcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIiICsKICAgICAgIkJcMDEwXG5cMDA2U2luZ2xlXCJ+XG5cMDAzQmFyXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdDJpXG5cMDA3Zm9vX2UiICsKICAgICAgInh0XDAyMisucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2giICsKICAgICAgImFzaC5Gb29cMDMwZCBcMDAxKFwwMTMyKy5wcm90b2J1Zl91bml0dGVzdC5saXRlX2UiICsKICAgICAgInF1YWxzX2FuZF9oYXNoLkJhclwiXDAzMFxuXDAxMEJhclByaW1lXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFx0XCJcMDA3XG5cMDA1RW1wdHlcIlwwMzZcblwwMDdNeUdyb3VwXDAyMlwwMjNcblwwMTNncm91cF92YWx1ZVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcdFwiZFxuXDAyMlRlc3RSZWN1cnNpdmVPbmVvZlwwMjJHXG5cMDAxclwwMzBcMDAxIFwwMDEoXDAxMzI6IiArCiAgICAgICIucHJvdG9idWZfdW5pdHRlc3QubGl0ZV9lcXVhbHNfYW5kX2hhc2guIiArCiAgICAgICJUZXN0UmVjdXJzaXZlT25lb2ZIXDAwMEJcMDA1XG5cMDAzRm9vOjtcblwwMDZ2YXJpbnRcMDIyKy4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYXNoLkYiICsKICAgICAgIm9vXDAzMGUgXDAwMShcMDA1OjxcblwwMDdmaXhlZDMyXDAyMisucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJsaXRlX2VxdWFsc19hbmRfaGFzaC5Gb29cMDMwZiBcMDAxKFwwMDc6PFxuXDAwN2ZpeGVkNiIgKwogICAgICAiNFwwMjIrLnByb3RvYnVmX3VuaXR0ZXN0LmxpdGVfZXF1YWxzX2FuZF9oYSIgKwogICAgICAic2guRm9vXDAzMGcgXDAwMShcMDA2Om1cblwwMDdteWdyb3VwXDAyMisucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5Gb29cMDMwaCBcMDAxKFxuMi8ucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5saXRlX2VxdWFsc19hbmRfaGFzaC5NeUdyIiArCiAgICAgICJvdXAiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9UZXN0T25lb2ZFcXVhbHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdE9uZW9mRXF1YWxzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RPbmVvZkVxdWFsc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTmFtZSIsICJWYWx1ZSIsICJPbmVvZkZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfRm9vX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgIkJhciIsICJNeU1hcCIsICJTaW50NjQiLCAiTXlHcm91cCIsICJTaW5nbGUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fTXlNYXBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeU1hcEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeU1hcEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9Gb29fTXlHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeUdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Zvb19NeUdyb3VwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX0Jhcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9CYXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOYW1lIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyUHJpbWVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyUHJpbWVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfQmFyUHJpbWVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk5hbWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9FbXB0eV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9FbXB0eV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9FbXB0eV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9NeUdyb3VwX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX015R3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfTXlHcm91cF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiR3JvdXBWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2xpdGVfZXF1YWxzX2FuZF9oYXNoX1Rlc3RSZWN1cnNpdmVPbmVvZl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9saXRlX2VxdWFsc19hbmRfaGFzaF9UZXN0UmVjdXJzaXZlT25lb2ZfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfbGl0ZV9lcXVhbHNfYW5kX2hhc2hfVGVzdFJlY3Vyc2l2ZU9uZW9mX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSIiwgIkZvbyIsIH0pOwogICAgdmFyaW50LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkpOwogICAgZml4ZWQzMi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEpKTsKICAgIGZpeGVkNjQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyKSk7CiAgICBteUdyb3VwLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMykpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAQIKAAoAAAAAAAAAIQAmbx6fMgAAADIAAAAUAAAAAAAAAAAAAAAAAAAAAABNRVRBLUlORi9NQU5JRkVTVC5NRlBLAQIKAAoAAAAAAAAAIQA8uDjjilkAAIpZAAAaAAAAAAAAAAAAAAAAAGQAAABhbnlfdGVzdC9BbnlUZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQAIldpUsm8FALJvBQAvAAAAAAAAAAAAAAAAACZaAABjb20vZ29vZ2xlL3Byb3RvYnVmL0ZpZWxkUHJlc2VuY2VUZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQDfaFzWo6oDAKOqAwAtAAAAAAAAAAAAAAAAACXKBQBjb20vZ29vZ2xlL3Byb3RvYnVmL1BhY2tlZEZpZWxkVGVzdFByb3RvLmphdmFQSwECCgAKAAAAAAAAACEAh3QQ76z+AACs/gAAOQAAAAAAAAAAAAAAAAATdQkAY29tL2dvb2dsZS9wcm90b2J1Zi9Qcm90bzJVbmtub3duRW51bVZhbHVlc1Rlc3RQcm90by5qYXZhUEsBAgoACgAAAAAAAAAhABrV/aKgigsAoIoLADAAAAAAAAAAAAAAAAAAFnQKAGNvbS9nb29nbGUvcHJvdG9idWYvVGVzdEJhZElkZW50aWZpZXJzUHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQDtdPlbdcozAHXKMwAuAAAAAAAAAAAAAAAAAAT/FQBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvUHJvdG8yVGVzdGluZy5qYXZhUEsBAgoACgAAAAAAAAAhANwCY2/Q5DMA0OQzADIAAAAAAAAAAAAAAAAAxclJAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9Qcm90bzJUZXN0aW5nTGl0ZS5qYXZhUEsBAgoACgAAAAAAAAAhAPlv1fPTdy8A03cvAC4AAAAAAAAAAAAAAAAA5a59AGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9Qcm90bzNUZXN0aW5nLmphdmFQSwECCgAKAAAAAAAAACEA3pd0aoFZLwCBWS8AMgAAAAAAAAAAAAAAAAAEJ60AY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL1Byb3RvM1Rlc3RpbmdMaXRlLmphdmFQSwECCgAKAAAAAAAAACEAW2rFhb41AQC+NQEAXwAAAAAAAAAAAAAAAADVgNwAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3RleHRmb3JtYXQvcGVyZm9ybWFuY2UvcHJvdG8yL1Byb3RvMlRleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmphdmFQSwECCgAKAAAAAAAAACEAwjP9jRbcAAAW3AAAXwAAAAAAAAAAAAAAAAAQt90AY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3RleHRmb3JtYXQvcGVyZm9ybWFuY2UvcHJvdG8zL1Byb3RvM1RleHRGb3JtYXRQZXJmb3JtYW5jZVByb3RvLmphdmFQSwECCgAKAAAAAAAAACEAAvMIX7RRAQC0UQEANwAAAAAAAAAAAAAAAACjk94AY29tL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVyc3Rlc3QvV3JhcHBlcnNUZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQADUMF9pgQAAKYEAAAjAAAAAAAAAAAAAAAAAKzl3wBkZXByZWNhdGVkX2ZpbGUvRGVwcmVjYXRlZEZpbGUuamF2YVBLAQIKAAoAAAAAAAAAIQDs2YOrY8oAAGPKAAAvAAAAAAAAAAAAAAAAAJPq3wBkeW5hbWljbWVzc2FnZXRlc3QvRHluYW1pY01lc3NhZ2VUZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQDSZKYoIqMJACKjCQAoAAAAAAAAAAAAAAAAAEO14ABtYXBfbGl0ZV90ZXN0L01hcEZvclByb3RvMlRlc3RQcm90by5qYXZhUEsBAgoACgAAAAAAAAAhANqSp89czQkAXM0JAB8AAAAAAAAAAAAAAAAAq1jqAG1hcF9saXRlX3Rlc3QvTWFwVGVzdFByb3RvLmphdmFQSwECCgAKAAAAAAAAACEA6K1gBcGFCQDBhQkAIwAAAAAAAAAAAAAAAABEJvQAbWFwX3Rlc3QvTWFwRm9yUHJvdG8yVGVzdFByb3RvLmphdmFQSwECCgAKAAAAAAAAACEA3biziwMQAAADEAAAKAAAAAAAAAAAAAAAAABGrP0AbWFwX3Rlc3QvTWFwSW5pdGlhbGl6YXRpb25PcmRlclRlc3QuamF2YVBLAQIKAAoAAAAAAAAAIQDtI3SUE7EJABOxCQAaAAAAAAAAAAAAAAAAAI+8/QBtYXBfdGVzdC9NYXBUZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQDguh2tTF8AAExfAAAWAAAAAAAAAAAAAAAAANptBwFtYXBfdGVzdC9NZXNzYWdlMS5qYXZhUEsBAgoACgAAAAAAAAAhACz51USlBAAApQQAAB8AAAAAAAAAAAAAAAAAWs0HAW1hcF90ZXN0L01lc3NhZ2UxT3JCdWlsZGVyLmphdmFQSwECCgAKAAAAAAAAACEADQUmYeQzAADkMwAAHAAAAAAAAAAAAAAAAAA80gcBbWFwX3Rlc3QvUmVkYWN0QWxsVHlwZXMuamF2YVBLAQIKAAoAAAAAAAAAIQCPvx6ZYQEAAGEBAAAlAAAAAAAAAAAAAAAAAFoGCAFtYXBfdGVzdC9SZWRhY3RBbGxUeXBlc09yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhACD9YHm+8wAAvvMAACkAAAAAAAAAAAAAAAAA/gcIAXByb3RvMl90ZXN0X2NoZWNrX3V0ZjgvVGVzdENoZWNrVXRmOC5qYXZhUEsBAgoACgAAAAAAAAAhAH4YxPGyyAAAssgAADIAAAAAAAAAAAAAAAAAA/wIAXByb3RvMl90ZXN0X2NoZWNrX3V0Zjhfc2l6ZS9UZXN0Q2hlY2tVdGY4U2l6ZS5qYXZhUEsBAgoACgAAAAAAAAAhAIeqm1urCQAAqwkAACoAAAAAAAAAAAAAAAAABcUJAXByb3RvYnVmX3VuaXR0ZXN0L0NhY2hlZEZpZWxkU2l6ZVRlc3QuamF2YVBLAQIKAAoAAAAAAAAAIQCrySSdB2EAAAdhAAAdAAAAAAAAAAAAAAAAAPjOCQFwcm90b2J1Zl91bml0dGVzdC9FbmdpbmUuamF2YVBLAQIKAAoAAAAAAAAAIQC93bcgDQUAAA0FAAAmAAAAAAAAAAAAAAAAADowCgFwcm90b2J1Zl91bml0dGVzdC9FbmdpbmVPckJ1aWxkZXIuamF2YVBLAQIKAAoAAAAAAAAAIQCOWJumMQsAADELAAAmAAAAAAAAAAAAAAAAAIs1CgFwcm90b2J1Zl91bml0dGVzdC9FbnVtV2l0aE5vT3V0ZXIuamF2YVBLAQIKAAoAAAAAAAAAIQBWSfWNBCQCAAQkAgAlAAAAAAAAAAAAAAAAAABBCgFwcm90b2J1Zl91bml0dGVzdC9MYXp5RmllbGRzTGl0ZS5qYXZhUEsBAgoACgAAAAAAAAAhANeHW8fC7wAAwu8AACkAAAAAAAAAAAAAAAAAR2UMAXByb3RvYnVmX3VuaXR0ZXN0L01lc3NhZ2VXaXRoTm9PdXRlci5qYXZhUEsBAgoACgAAAAAAAAAhACaLeq2mCQAApgkAADIAAAAAAAAAAAAAAAAAUFUNAXByb3RvYnVmX3VuaXR0ZXN0L01lc3NhZ2VXaXRoTm9PdXRlck9yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhAPOsNazuFQAA7hUAAC0AAAAAAAAAAAAAAAAARl8NAXByb3RvYnVmX3VuaXR0ZXN0L011bHRpcGxlRmlsZXNUZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQCrvrz9hhAAAIYQAAAlAAAAAAAAAAAAAAAAAH91DQFwcm90b2J1Zl91bml0dGVzdC9OZXN0ZWRCdWlsZGVycy5qYXZhUEsBAgoACgAAAAAAAAAhAKxFN5AiSgAAIkoAACYAAAAAAAAAAAAAAAAASIYNAXByb3RvYnVmX3VuaXR0ZXN0L05lc3RlZEV4dGVuc2lvbi5qYXZhUEsBAgoACgAAAAAAAAAhALBBrWF0TAAAdEwAACoAAAAAAAAAAAAAAAAArtANAXByb3RvYnVmX3VuaXR0ZXN0L05lc3RlZEV4dGVuc2lvbkxpdGUuamF2YVBLAQIKAAoAAAAAAAAAIQCQvoAr3JEAANyRAAApAAAAAAAAAAAAAAAAAGodDgFwcm90b2J1Zl91bml0dGVzdC9Ob25OZXN0ZWRFeHRlbnNpb24uamF2YVBLAQIKAAoAAAAAAAAAIQBHXcvdHJYAAByWAAAtAAAAAAAAAAAAAAAAAI2vDgFwcm90b2J1Zl91bml0dGVzdC9Ob25OZXN0ZWRFeHRlbnNpb25MaXRlLmphdmFQSwECCgAKAAAAAAAAACEAEWwSiQDXAAAA1wAANAAAAAAAAAAAAAAAAAD0RQ8BcHJvdG9idWZfdW5pdHRlc3QvT3V0ZXJDbGFzc05hbWVUZXN0Mk91dGVyQ2xhc3MuamF2YVBLAQIKAAoAAAAAAAAAIQAWW/OI1ZUAANWVAAA0AAAAAAAAAAAAAAAAAEYdEAFwcm90b2J1Zl91bml0dGVzdC9PdXRlckNsYXNzTmFtZVRlc3QzT3V0ZXJDbGFzcy5qYXZhUEsBAgoACgAAAAAAAAAhAAl7PBy/RgAAv0YAADMAAAAAAAAAAAAAAAAAbbMQAXByb3RvYnVmX3VuaXR0ZXN0L091dGVyQ2xhc3NOYW1lVGVzdE91dGVyQ2xhc3MuamF2YVBLAQIKAAoAAAAAAAAAIQAsrxLTOyEAADshAAApAAAAAAAAAAAAAAAAAH36EAFwcm90b2J1Zl91bml0dGVzdC9TZXJ2aWNlV2l0aE5vT3V0ZXIuamF2YVBLAQIKAAoAAAAAAAAAIQDBOmIbI14AACNeAAAxAAAAAAAAAAAAAAAAAP8bEQFwcm90b2J1Zl91bml0dGVzdC9UZXN0Q2FjaGVkRmllbGRTaXplTWVzc2FnZS5qYXZhUEsBAgoACgAAAAAAAAAhAEqrcg60BQAAtAUAADoAAAAAAAAAAAAAAAAAcXoRAXByb3RvYnVmX3VuaXR0ZXN0L1Rlc3RDYWNoZWRGaWVsZFNpemVNZXNzYWdlT3JCdWlsZGVyLmphdmFQSwECCgAKAAAAAAAAACEAB024KYxrAACMawAAKAAAAAAAAAAAAAAAAAB9gBEBcHJvdG9idWZfdW5pdHRlc3QvVGVzdEN1c3RvbU9wdGlvbnMuamF2YVBLAQIKAAoAAAAAAAAAIQA/C48Z4j8AAOI/AAAhAAAAAAAAAAAAAAAAAE/sEQFwcm90b2J1Zl91bml0dGVzdC9UaW1pbmdCZWx0LmphdmFQSwECCgAKAAAAAAAAACEAYruLunQCAAB0AgAAKgAAAAAAAAAAAAAAAABwLBIBcHJvdG9idWZfdW5pdHRlc3QvVGltaW5nQmVsdE9yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhAAzUYsEheAAAIXgAAB4AAAAAAAAAAAAAAAAALC8SAXByb3RvYnVmX3VuaXR0ZXN0L1ZlaGljbGUuamF2YVBLAQIKAAoAAAAAAAAAIQCEQ97rqAUAAKgFAAAnAAAAAAAAAAAAAAAAAImnEgFwcm90b2J1Zl91bml0dGVzdC9WZWhpY2xlT3JCdWlsZGVyLmphdmFQSwECCgAKAAAAAAAAACEAf7mcyjxGAAA8RgAAHAAAAAAAAAAAAAAAAAB2rRIBcHJvdG9idWZfdW5pdHRlc3QvV2hlZWwuamF2YVBLAQIKAAoAAAAAAAAAIQBw7h9TGgMAABoDAAAlAAAAAAAAAAAAAAAAAOzzEgFwcm90b2J1Zl91bml0dGVzdC9XaGVlbE9yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhABSRVjngdgMA4HYDAD0AAAAAAAAAAAAAAAAASfcSAXByb3RvYnVmX3VuaXR0ZXN0L2xpdGVfZXF1YWxzX2FuZF9oYXNoL0xpdGVFcXVhbHNBbmRIYXNoLmphdmFQSwUGAAAAADUANQBtEgAAhG4WAQAA